Flutterで列にListViewを追加する方法


124

Flutterアプリの簡単なログインページを作成しようとしています。TextFieldsおよびLogin / Signinボタンを正常に作成しました。水平方向のリストビューを追加したい。コードを実行すると、要素が表示されなくなります。ListViewを使用せずに実行すると、問題はなくなります。これを正しく行うにはどうすればよいですか?

return new MaterialApp(
        home: new Scaffold(
          appBar: new AppBar(
            title: new Text("Login / Signup"),
          ),
          body: new Container(
            child: new Center(
              child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  new TextField(
                    decoration: new InputDecoration(
                      hintText: "E M A I L    A D D R E S S"
                    ),
                  ),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new TextField(obscureText: true,
                    decoration: new InputDecoration(
                      hintText: "P A S S W O R D"
                    ),
                    ),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new TextField(decoration: new InputDecoration(
                    hintText: "U S E R N A M E"
                  ),),
                  new RaisedButton(onPressed: null,
                  child:  new Text("SIGNUP"),),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new RaisedButton(onPressed: null,
                  child: new Text("LOGIN"),),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new ListView(scrollDirection: Axis.horizontal,
                  children: <Widget>[
                    new RaisedButton(onPressed: null,
                    child: new Text("Facebook"),),
                    new Padding(padding: new EdgeInsets.all(5.00)),
                    new RaisedButton(onPressed: null,
                    child: new Text("Google"),)
                  ],)

                ],
              ),
            ),
            margin: new EdgeInsets.all(15.00),
          ),
        ),
      );

回答:


73

コンソール出力を確認できます。エラーを出力します:

次のアサーションは、performResize()の間にスローされました:水平ビューポートに無制限の高さが指定されました。ビューポートは、交差軸で拡張してコンテナを塗りつぶし、子を拘束して交差軸での範囲に一致させます。この場合、水平ビューポートには、拡張可能な垂直スペースが無制限に与えられました。

水平リストに高さ制約を追加する必要があります。たとえば、高さのあるコンテナでラップします。

Container(
  height: 44.0,
  child: ListView(
    scrollDirection: Axis.horizontal,
    children: <Widget>[
      RaisedButton(
        onPressed: null,
        child: Text("Facebook"),
      ),
      Padding(padding: EdgeInsets.all(5.00)),
      RaisedButton(
        onPressed: null,
        child: Text("Google"),
      )
    ],
  ),
)

6
次の2つの答えは、別の2つの解決策を示し、何が起こっているかを説明します。
パシュトゥート

299

私もこの問題を抱えています。私の解決策は、Expandedウィジェットを使用して残りのスペースを拡張することです。

new Column(
  children: <Widget>[
    new Expanded(
      child: horizontalList,
    )
  ],
);

2
これは、ListViewの高さ/幅を可変サイズにすることができるため、優れたソリューションです。たとえば、残りのスペースを占有する場合などです。正確な高さ/幅を知るのが難しい場合に、さまざまな画面サイズを考慮することができます。
ダニエルアレン

1
これは受け入れられる答えになるはずです。このソリューションにより、ListViewは、メディアクエリを処理する必要なく、画面の残りの部分を取得できます。
Terence Ponce

私はFlutterを使い始めたばかりなので、なぜこれが機能するのかを知ることはできませんが、機能してうれしいです。ありがとうございました。Flutterのエラーメッセージは、専門家以外のユーザーにとってこの問題の根本的な原因を説明するのにあまり役に立ちませんでした。
devdanke

ありがとう、あなたの答えは私の時間を節約します。
リカットジュリアス

125

エラーの理由:

Column主軸方向(縦軸)の最大サイズまで拡大し、ListView

ソリューション

したがって、の高さを制限する必要がありますListView。それを行うには多くの方法があり、あなたのニーズに最適なものを選択できます。


  1. 使用ListView中に残りのスペースをすべて使用できるようにするColumn場合Expanded

    Column(
      children: <Widget>[
        Expanded(
          child: ListView(...),
        )
      ],
    )

  1. ListView特定のものに制限したい場合はheight、を使用できますSizedBox

    Column(
      children: <Widget>[
        SizedBox(
          height: 200, // constrain height
          child: ListView(),
        )
      ],
    )

  1. あなたListViewが小さいなら、あなたはshrinkWrapそれで財産を試みるかもしれません。

    Column(
      children: <Widget>[
        ListView(
          shrinkWrap: true, // use it
        )
      ],
    )

私の身長は固定されるべきではなく、他の答えは私にとってうまくいかなかった= /
Daniel Vilela

1
@DanielVilelaオプション1でうまくいくはずです。そうでなければ質問としてそれを投稿してください、そして、私が利用できるならば、私はそれに答えることができます。
CopsOnRoad

1
うまくいきました!ありがとう。Expanded()をいくつかの戦略的な場所に配置する必要がありました。
ダニエルビレラ

ありがとう、エキスパンドについては考えていませんでした。
GilvanAndré19年

shrinkWrapをありがとう:ListView()でtrue
Rana Hyder

18

私はSingleChildScrollView親として、1つのColumnウィジェット、最後の子としてリストビューウィジェットを持っています。

リストビューでこれらのプロパティを追加すると、うまくいきました。

  physics: NeverScrollableScrollPhysics(),
  shrinkWrap: true,
  scrollDirection: Axis.vertical,

14

展開されたウィジェットは、利用可能なスペースで可能な限りサイズを大きくします。ListViewは基本的に高さが無限であるため、エラーが発生します。

 Column(
  children: <Widget>[
    Flexible(
      child: ListView(...),
    )
  ],
)

ここでは、フレキシブルウィジェットを使用する必要があります。これは、フルスクリーンでレンダリングするのに十分なウィジェットがない場合でも、エキスパンドが全画面表示になるため、必要なスペースのみを使用するためです。


10

実際、ドキュメントを読むときは、ListViewが展開ウィジェット内にある必要があります。

  Widget build(BuildContext context) {
return Scaffold(
    body: Column(
  children: <Widget>[
    Align(
      child: PayableWidget(),
    ),
    Expanded(
      child: _myListView(context),
    )
  ],
));

}


7

上記の他の人が述べたように、Expandedを使用したリストビューのラップがソリューションです。

ただし、ネストされた列を処理する場合は、ListViewを特定の高さに制限する必要もあります(この問題に多く直面しました)。

誰か他の解決策がある場合は、コメントで言及するか、回答を追加してください。

  SingleChildScrollView(
   child: Column(
     children: <Widget>[
       Image(image: ),//<< any widgets added
       SizedBox(),
       Column(
         children: <Widget>[
           Text('header'),  //<< any widgets added
            Expanded(child: 
            ListView.builder(
              //here your code
               scrollDirection: Axis.horizontal,
        itemCount: items.length,
        itemBuilder: (BuildContext context, int index) {
            return Container();
                   } 
         )
        ),
        Divider(),//<< any widgets added
         ],
       ),

     ],
   ), 
  );

ネストされた列では、拡張を使用せず、shrikWrap:trueを使用してください。true:physics:listViewのNeverScrolPhysics()プロパティ
Mohamed Kamel

5

あなたは使用することができますFlexし、Flexibleウィジェット。例えば:

Flex(
direction: Axis.vertical,
children: <Widget>[
    ... other widgets ...
    Flexible(
        flex: 1,
        child: ListView.builder(
        itemCount: ...,
        itemBuilder: (context, index) {
            ...
        },
        ),
    ),
],

);


-1

スライバーを使用してみてください。

Container(
    child: CustomScrollView(
      slivers: <Widget>[
        SliverList(
          delegate: SliverChildListDelegate(
            [
              HeaderWidget("Header 1"),
              HeaderWidget("Header 2"),
              HeaderWidget("Header 3"),
              HeaderWidget("Header 4"),
            ],
          ),
        ),
        SliverList(
          delegate: SliverChildListDelegate(
            [
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
              BodyWidget(Colors.green),
              BodyWidget(Colors.orange),
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
            ],
          ),
        ),
        SliverGrid(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          delegate: SliverChildListDelegate(
            [
              BodyWidget(Colors.blue),
              BodyWidget(Colors.green),
              BodyWidget(Colors.yellow),
              BodyWidget(Colors.orange),
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
            ],
          ),
        ),
      ],
    ),
  ),
)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.