81 votes

Comment faire défiler une page dans flutter

Mon code pour une page est comme ceci. J'ai besoin de faire défiler la partie en dessous de la barre d'application.

@override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(... ),
      body: new Stack(
        children: <Widget>[
          new Container(
            decoration: BoxDecoration(
                image: DecorationImage(...),
          new Column(children: [
            new Container(...),
            new Container(...... ),
            new Padding(
              child: SizedBox(
                child: RaisedButton(..),
            ),
            new Divider(),
            new Column(
              children: <Widget>[
                new Container(
                  child: new Row(
                    children: <Widget>[
                      new Expanded(
                        child: new Text(  ),
                      ),
                      new IconButton(
                        icon: IconButton(..),
                        onPressed: () {
                          _changed(true, "type");
                        },
                      ),
                    ],
                  ),
                ),
                visibilityPropertyType
                    ? new Container(
                        margin: EdgeInsets.all(24.0),
                        child: new Column(
                          children: <Widget>[
                            new Row(
                              children: <Widget>[
                                new Expanded(... ),
                                new RaisedButton(..)
                              ],
                            ),
                            new Padding(
                              padding: const EdgeInsets.only(top: 10.0),
                              child: new Row(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceEvenly,
                                children: <Widget>[
                                  new Column(
                                    children: <Widget>[
                                      new Row(  
                                        children: <Widget>[.. ]),
                                      new Row(
                                        children: <Widget>[]),
                                      new Row(
                                        children: <Widget>[]),
                                      new Row(
                                        children: <Widget>[],
                                  ),
                                  new Column(
                                    children: <Widget>[
                                      new Row(
                                        children: <Widget>[],
                                      ),
                                    ],
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ))
                    : new Container(),
              ],
            ),
            new Divider(
              color: Colors.white,
            )
          ])
        ],
      ),
    );
  }

J'ai besoin de faire défiler une partie du corps. Comment puis-je mettre en œuvre ce défilement ? S'il existe une méthode de défilement personnalisée, j'ai déjà essayé. Scrollable et SingleChildScrollView mais ne répond pas à mes besoins. Lorsque j'ai utilisé SinglechildScrollView il se produit une erreur BoxConstraints force une hauteur infinie. si j'ai supprimé LayoutBuilder il provoque A RenderFlex overflowed by 22 pixels on the bottom erreur

164voto

Jaswant Singh Points 1745

Enveloppez votre arbre de widgets dans un SingleChildScrollView.

 body: SingleChildScrollView(
child: Stack(
    children: <Widget>[
      new Container(
        decoration: BoxDecoration(
            image: DecorationImage(...),
      new Column(children: [
        new Container(...),
        new Container(...... ),
        new Padding(
          child: SizedBox(
            child: RaisedButton(..),
        ),
....
...
 ); // Single child scroll view

N'oubliez pas que SingleChildScrollView ne peut avoir qu'un seul widget direct (tout comme ScrollView dans Android).

27 votes

Crashes pour moi avec RenderFlex children have non-zero flex but incoming height constraints are unbounded.

1 votes

Utilisez-vous un ListView ou quelque chose de défilable à l'intérieur du SingleChildScrollView ? Si oui, la définition de la propriété shringWrap de ce widget à true pourrait résoudre le problème.

2 votes

Essayez d'enlever Expanded si vous en avez un.

29voto

Vineeth Mohan Points 542

Merci pour votre aide. A partir de vos suggestions, j'ai trouvé une solution comme celle-ci.

new LayoutBuilder(
        builder:
            (BuildContext context, BoxConstraints viewportConstraints) {
          return SingleChildScrollView(
            child: ConstrainedBox(
              constraints:
                  BoxConstraints(minHeight: viewportConstraints.maxHeight),
              child: Column(children: [
             // remaining stuffs
              ]),
            ),
          );
        },
      )

4 votes

LayoutBuilder + BoxConstraints + ConstrainedBox - fait des miracles ! Par exemple, dans mon cas, je voulais un défilement horizontal imbriqué dans une colonne. Le problème était que, par défaut, le scroll horizontal centre son contenu, quoi que vous fassiez. J'ai donc dû placer SingleChildScrollView à l'intérieur d'une ConstrainedBox avec maxWidth : viewportConstraints.maxWidth, minWidth : viewportConstraints.maxWidth. Ainsi, s'il y a peu de contenu, il s'aligne à gauche, et s'il y a beaucoup de contenu (plus d'une largeur d'écran), il commence à défiler.

0 votes

Cette solution fonctionne, mais le layout builder continue de construire tous les widgets lorsqu'il y a une interaction avec la page, par exemple la liste de défilement, le bouton de clic. Est-ce que c'est bon ? Si vous voulez vérifier la reconstruction, vous pouvez charger la bibliothèque randomColor depuis la pub et l'assigner à n'importe quel widget de votre page. Vous essayez d'interagir avec n'importe lequel de vos widgets sous layout builder. Vous pouvez voir que le widget qui a assigné randomColor change de couleur à chaque fois. Est-ce que c'est bien ? L'avis d'un expert est requis.

0 votes

Layout Builder réoriente l'enfant à chaque fois qu'il y a une interaction avec l'un des widgets enfants.

15voto

Sanjayrajsinh Points 1098

Deux façons d'ajouter le défilement dans la page

1. Utilisation de SingleChildScrollView :

     SingleChildScrollView(
          child: Column(
            children: [
              Container(....),
              SizedBox(...),
              Container(...),
              Text(....)
            ],
          ),
      ),

2. Utilisation de ListView : Le ListView fournit par défaut le défilement, il n'est pas nécessaire d'ajouter un widget supplémentaire pour le défilement.

     ListView(
          children: [
            Container(..),
            SizedBox(..),
            Container(...),
            Text(..)
          ],
      ),

7voto

WitVault Points 9196

Vous pouvez essayer CustomScrollView . Placez votre CustomScrollView à l'intérieur de Column Widget.

Par exemple -

class App extends StatelessWidget {

 App({Key key}): super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
          title: const Text('AppBar'),
      ),
      body: new Container(
          constraints: BoxConstraints.expand(),
          decoration: new BoxDecoration(
            image: new DecorationImage(
              alignment: Alignment.topLeft,
              image: new AssetImage('images/main-bg.png'),
              fit: BoxFit.cover,
            )
          ),
          child: new Column(
            children: <Widget>[               
              Expanded(
                child: new CustomScrollView(
                  scrollDirection: Axis.vertical,
                  shrinkWrap: false,
                  slivers: <Widget>[
                    new SliverPadding(
                      padding: const EdgeInsets.symmetric(vertical: 0.0),
                      sliver: new SliverList(
                        delegate: new SliverChildBuilderDelegate(
                          (context, index) => new YourRowWidget(),
                          childCount: 5,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          )),
    );
  }
}

Dans le code ci-dessus, j'affiche une liste d'éléments (5 au total) dans le CustomScrollView. YourRowWidget Le widget est rendu 5 fois comme élément de liste. En général, vous devez rendre chaque ligne en fonction de certaines données.

Vous pouvez supprimer la propriété de décoration du widget Container, qui sert uniquement à fournir une image de fond.

3voto

Rohit Soni Points 119

Vous pouvez utiliser celle-ci et c'est la meilleure pratique.

SingleChildScrollView(
  child: Column(
    children: <Widget>[
      //Your Widgets
      //Your Widgets,
      //Your Widgets
    ],
  ),
);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X