web-dev-qa-db-fra.com

flutter implémenter des en-têtes collants et l'effet snap to item

Ces derniers jours, j'ai lu la documentation du framework flutter et surtout la partie sliver mais je ne sais pas trop par où commencer. J'essaie d'implémenter les en-têtes collants et l'effet snap. La RenderSliverList pourrait-elle être un bon début? Dois-je réorganiser les choses? Dois-je faire un dessin supplémentaire? Et si oui, où?

Toute aide sur où commencer serait d'une grande aide, merci d'avance!

Edit: Je pense que j'ai compris la partie mise en page maintenant, mais je n'arrive pas à trouver où la peinture est censée se produire.

Edit 2: Pour plus de précision, il s'agit de "l'effet d'en-tête collant" souhaité:

Comment puis-je créer des en-têtes collants dans RecyclerView? (Sans bibliothèque externe)

et c'est l'effet "snap":

https://rubensousa.github.io/2016/08/recyclerviewsnap

11
Norbert

Pour "l'effet d'en-tête collant", j'ai rencontré ce problème moi-même, j'ai donc créé ce package pour gérer les en-têtes collants avec des éclats: https://github.com/letsar/flutter_sticky_header

Flutter Sticky Headers

Pour l'utiliser, vous devez créer un SliverStickyHeader par section dans un CustomScrollView.

Une section peut être écrite comme ceci:

new SliverStickyHeader(
  header: new Container(
    height: 60.0,
    color: Colors.lightBlue,
    padding: EdgeInsets.symmetric(horizontal: 16.0),
    alignment: Alignment.centerLeft,
    child: new Text(
      'Header #0',
      style: const TextStyle(color: Colors.white),
    ),
  ),
  sliver: new SliverList(
    delegate: new SliverChildBuilderDelegate(
      (context, i) => new ListTile(
            leading: new CircleAvatar(
              child: new Text('0'),
            ),
            title: new Text('List tile #$i'),
          ),
      childCount: 4,
    ),
  ),
);

Si vous le souhaitez, le code source complet de la démo ci-dessus est ici: https://github.com/letsar/flutter_sticky_header/blob/master/example/lib/main.Dart

J'espère que cela t'aidera.

17
Romain Rastel

C'est très simple:

Utilisez un CustomScrollView et donnez-lui comme enfant à la fois un SliverList et un SliverAppBar . Vous pouvez remplacer le SliverList par un SliverGrid si vous en avez besoin.

Ensuite, selon l'effet que vous souhaitez obtenir, vous pouvez définir quelques propriétés SliverAppBar :

  • casser
  • extendedHeight (+ flexibleSpace)
  • flottant
  • épinglé

En fin de compte, vous pourriez avoir quelque chose de similaire à:

new CustomScrollView(
    slivers: <Widget>[
        new SliverAppBar(
            title: new Text("Title"),
            snap: true,
            floating: true,
        ),
        new SliverFixedExtentList(
            itemExtent: 50.0,
            delegate: new SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                    return new Container(
                        alignment: Alignment.center,
                        color: Colors.lightBlue[100 * (index % 9)],
                        child: new Text('list item $index'),
                    );
                },
            ),
        ),
    ],
)

Encore mieux, vous pouvez concaténer différents comportements de défilement dans un seul CustomScrollView . Ce qui signifie que vous pouvez potentiellement avoir une grille suivie d'une liste en ajoutant simplement SliverGrid en tant qu'enfant à votre scrollView.

Je sais que je sais, le flottement est génial.

6
Rémi Rousselet

J'ai réussi à faire l'effet collant sur Flutter pour une application iOS en utilisant le code suivant - le mérite revient à ce morceau de code écrit ici d'où j'ai puisé mon inspiration ( https://github.com/flutter/flutter/ blob/master/examples/flutter_gallery/lib/demo/animation/home.Dart # L112 ):

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverAppBarDelegate({
    @required this.collapsedHeight,
    @required this.expandedHeight,}
      );

  final double expandedHeight;
  final double collapsedHeight;

  @override double get minExtent => collapsedHeight;
  @override double get maxExtent => math.max(expandedHeight, minExtent);

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return new Container(color: Colors.red,
        child: new Padding(
          padding: const EdgeInsets.only(
              left: 8.0, top: 8.0, bottom: 8.0, right: 8.0),
          child: new Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              new Text("Time"), new Text("Price"), new Text("Hotness")
            ],
          ),
        )
    );
  }

  @override
  bool shouldRebuild(@checked _SliverAppBarDelegate oldDelegate) {
    return expandedHeight != oldDelegate.expandedHeight
        || collapsedHeight != oldDelegate.collapsedHeight;
  }
}

Pour le rendre collant, ajoutez le _SliverAppBarDelegate à la liste des widgets silvers:

 new SliverPersistentHeader(delegate: new _SliverAppBarDelegate(collapsedHeight: 36.0, expandedHeight: 36.0), pinned: true, ),

Je ne sais pas vraiment comment faire en sorte que _SliverAppBarDelegate encapsule le contenu, j'ai dû lui fournir une taille de 36 pixels logiques pour le faire fonctionner. Si quelqu'un sait comment cela pourrait simplement envelopper le contenu, veuillez laisser un commentaire à la réponse ci-dessous.

enter image description here

3
Simon