web-dev-qa-db-fra.com

Comment utiliser Expanded dans SingleChildScrollView?

Comment utiliser Expanded dans SingleChildScrollView? J'ai un écran avec Image.network, ListView.builder et Row (TextFormField et bouton Icon). J'ai enveloppé ListView avec Expanded. Comment encapsuler cette colonne avec SingleChildScrollView? J'ai besoin de déplacer l'écran lorsque le clavier est ouvert pour voir ce que j'écris. Lorsque j'enveloppe ma colonne, j'ai cette erreur.

      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Container(
              child: GestureDetector(
                child:
                Image.network(
                  postOne.imageUrl,
                  fit: BoxFit.fitWidth,
                  height: MediaQuery
                      .of(context)
                      .size
                      .width,
                  width: MediaQuery
                      .of(context)
                      .size
                      .width,
                ),
                onLongPress: () {},
                onDoubleTap: () {},
              ),
            ),
            Expanded(
              //height: MediaQuery.of(context).size.width*0.33,
              child: ListView.builder(
                  itemCount: commentList.length,
                  itemBuilder: (context, position) {
                    return GestureDetector(
                        onLongPress: () {},
                        child: Card(
                          child: Padding(
                            padding: EdgeInsets.all(5.0),
                            child: new CheckboxListTile(
                                title: new Text(commentList
                                    .elementAt(position)
                                    .coment,
                                  style: TextStyle(fontSize: 18.0),),
                                value: values[commentList
                                    .elementAt(position)
                                    .coment],
                                onChanged: (bool value) {}),
                          ),
                        )
                    );
                  }
              ),
            ),
            Container(
              child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    new Flexible(
                      child: Theme(
                        data: new ThemeData(
                            brightness: Brightness.light,
                            primarySwatch: Colors.grey,
                            inputDecorationTheme: new InputDecorationTheme(
                              labelStyle: new TextStyle(
                                  color: Colors.black45, fontSize: 18.0
                              ),
                            )
                        ),
                        child: new Form(
                          key: _formKey,
                          child: new TextFormField(
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'Please enter the comment';
                              }
                            },
                            controller: commentController,
                            decoration: new InputDecoration(
                              labelText: "Add comment",
                              //hintText: 'Add comment'
                            ),
                            keyboardType: TextInputType.text,
                          ),
                        ),
                      ),
                    ),
                    new Container(
                        margin: EdgeInsets.only(left: 10.0, top: 12.0),
                        child: new IconButton(
                            icon: new Icon(Icons.send, color: Colors.black,),
                            onPressed: () {}
                        )
                    ),
                  ]),
            ),
          ],
        ),
      ),
I/flutter ( 6816): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 6816): The following assertion was thrown during performLayout():
I/flutter ( 6816): RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I/flutter ( 6816): When a column is in a parent that does not provide a finite height constraint, for example if it is
I/flutter ( 6816): in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
I/flutter ( 6816): flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
I/flutter ( 6816): space in the vertical direction.
I/flutter ( 6816): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
I/flutter ( 6816): cannot simultaneously expand to fit its parent.
I/flutter ( 6816): Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
I/flutter ( 6816): children (using Flexible rather than Expanded). This will allow the flexible children to size
I/flutter ( 6816): themselves to less than the infinite remaining space they would otherwise be forced to take, and
I/flutter ( 6816): then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
I/flutter ( 6816): constraints provided by the parent.
I/flutter ( 6816): The affected RenderFlex is:
I/flutter ( 6816):   RenderFlex#9f534 relayoutBoundary=up11 NEEDS-LAYOUT NEEDS-Paint
I/flutter ( 6816): The creator information is set to:
I/flutter ( 6816):   Column ← _SingleChildViewport ← IgnorePointer-[GlobalKey#3670d] ← Semantics ← Listener ←
I/flutter ( 6816):   _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#4878e] ←
I/flutter ( 6816):   Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#c5885] ← RepaintBoundary ← CustomPaint ←
I/flutter ( 6816):   ⋯
I/flutter ( 6816): The nearest ancestor providing an unbounded width constraint is:
I/flutter ( 6816):   _RenderSingleChildViewport#155d8 relayoutBoundary=up10 NEEDS-LAYOUT NEEDS-Paint
I/flutter ( 6816):   creator: _SingleChildViewport ← IgnorePointer-[GlobalKey#3670d] ← Semantics ← Listener ←
I/flutter ( 6816):   _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#4878e] ←
I/flutter ( 6816):   Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#c5885] ← RepaintBoundary ← CustomPaint ←
I/flutter ( 6816):   RepaintBoundary ← ⋯
I/flutter ( 6816):   parentData: <none> (can use size)
I/flutter ( 6816):   constraints: BoxConstraints(0.0<=w<=440.8, 0.0<=h<=649.3)
I/flutter ( 6816):   size: MISSING
I/flutter ( 6816): See also: https://flutter.dev/layout/
I/flutter ( 6816): If this message did not help you determine the problem, consider using debugDumpRenderTree():
I/flutter ( 6816):   https://flutter.dev/debugging/#rendering-layer
I/flutter ( 6816):   http://docs.flutter.io/flutter/rendering/debugDumpRenderTree.html
I/flutter ( 6816): If none of the above helps enough to fix this problem, please don't hesitate to file a bug:
I/flutter ( 6816):   https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter ( 6816): 

screen

20
konto211541

La réponse est dans l'erreur elle-même. Lorsque la colonne se trouve dans une vue qui peut faire défiler, la colonne tente de réduire le retour à la ligne de son contenu, mais puisque vous avez utilisé Expanded en tant qu'enfant de la colonne, elle fonctionne en face de la colonne qui tente de réduire le retour à la ligne de ses enfants. Cela provoque cette erreur car ces deux directives sont complètement opposées.

Comme mentionné dans les journaux d'erreurs, essayez ce qui suit:

Pensez à définir mainAxisSize sur MainAxisSize.min (pour la colonne) et à utiliser FlexFit.loose convient pour le flexible (utilisez Flexible plutôt qu'Expanded).

12
nick.tdr

Essaye ça,

LayoutBuilder(
  builder: (context, constraint) {
    return SingleChildScrollView(
      child: ConstrainedBox(
        constraints: BoxConstraints(minHeight: constraint.maxHeight),
        child: IntrinsicHeight(
          child: Column(
            children: <Widget>[
              Text("Header"),
              Expanded(
                child: Container(
                  color: Colors.red,
                ),
              ),
              Text("Footer"),
            ],
          ),
        ),
      ),
    );
  },
)

J'ai obtenu cette solution à partir de problèmes git lorsque je suis dans la même situation. Je n'ai pas le lien git. Je pense que cela peut vous aider.

33
Crazy Lazy Cat

J'ai essayé la solution Vijaya Ragavan, mais j'ai fait quelques ajustements et cela fonctionne toujours. Pour utiliser Expanded avec SingleChildScrollView, j'ai utilisé ConstrainedBox et défini sa hauteur à la hauteur de l'écran (à l'aide de MediaQuery). Vous aurez juste besoin de vous assurer que le contenu de l'écran que vous mettez dans ConstrainedBox n'est pas plus grand que la hauteur de l'écran.

Sinon, définissez la hauteur de ConstrainedBox sur la hauteur du contenu que vous souhaitez afficher à l'écran.

SingleChildScrollView(
          child: ConstrainedBox(
            constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height),
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  Expanded(
                    child: Text('Hello World!'),
                  ),
                ],
             ),
           )
 )

Modifier: pour soustraire la hauteur de l'AppBar et/ou de la barre d'état, voir ci-dessous:

double screenHeightMinusAppBarMinusStatusBar = MediaQuery.of(context).size.height - appBar.preferredSize.height - MediaQuery.of(context).padding.top
3
Mimina

Comme déjà souligné, parce que vous utilisez un scrollable, vous ne pouvez pas vous étendre à l'infini (théoriquement parlant), c'est ce qui se passe lorsque vous essayez de développer votre ListView qui est imbriqué dans un SingleChildScrollView.

Vous pouvez essayer d'utiliser un NestedScrollView, ou, s'il correspond à vos demandes et parce que vous avez commenté cette ligne:

//height: MediaQuery.of(context).size.width*0.33,

Vous pouvez simplement envelopper votre ListView dans un ConstrainedBox (ou même juste un Container régulier) avec cette hauteur, par exemple, au lieu du Expanded, comme alors:

 Container(
         height: MediaQuery.of(context).size.width*0.33,
              child: ListView.builder(
                  itemCount: commentList.length,
                ...
               )
          )

Étant donné que vous êtes déjà dans un défilement, vous ne devriez pas avoir de problèmes avec des écrans plus petits, car l'arborescence entière est défilable.

0
Miguel Ruivo