Flutter - 在一个屏幕上显示两个ListView

24

我试图在另一个垂直的 listView.builder 上方添加一个水平的listView.builder。两个listViews 都应该有文本显示在上面。

到目前为止,我做的是这样的,只绘制了顶部的水平listView.builder,当我尝试点击底部垂直listView.builder 应该绘制的位置时,应用程序会在调试中崩溃,我得到错误:NoSuchMethodError: The getter 'visible' was called on null.

此外,我不知道如何添加这两个text字段,所以我把它们留空了。

我有相当多的代码,如果您需要查看更多,请在此处查看。

Widget _cryptoWidget() {
return new Container(
    child: new Column(
      children: <Widget>[
        new Flexible(
          child: new ListView.builder(
              scrollDirection: Axis.horizontal,
              itemBuilder: (BuildContext context, int index) {
              return _listViewFiller();
            }
          ),
        ),
        new Flexible(
          child: new RefreshIndicator(
          key: refreshKey,
          child: new ListView.builder(
            scrollDirection: Axis.horizontal,
            itemCount: _currencies.length,
            itemBuilder: (BuildContext context, int index) {
              final int i = index ~/ 2;
              final Crypto currency = _currencies[i];
              final MaterialColor color = _colors[i % _colors.length];
              if (index.isOdd) {
                return new Divider();
              }
              return _getListItemUi(currency, color);
            },
          ),
          onRefresh:refreshList,
        ),
        )
      ],
    )
  );
 }

两个ListView都是水平方向的,Axis.horizontal。 - diegoveloper
我已经解决了这个问题,很快会回答自己的问题。 - Jake
刚刚需要修复一些位置错误。 - Jake
我的问题现在已经发布了。 - Jake
尝试将列表视图放置在滚动视图小部件中。并查看此链接,该问题在stackoverflow上相同。 - Can Karabag
1
@CanKarabag 这是你的问题吗? - Jake
3个回答

27
import 'package:flutter/material.dart';
import 'background.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
  title: 'Flutter Demo',
  theme: new ThemeData(
    primarySwatch: Colors.blue,
  ),
  debugShowCheckedModeBanner: false,
  home: new MyHomePage(title: 'Popular'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
List<String> items = [
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5",
"Item 6",
"Item 7",
"Item 8"
];

@override
Widget build(BuildContext context) {
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;

final headerList = new ListView.builder(
  itemBuilder: (context, index) {
    EdgeInsets padding = index == 0?const EdgeInsets.only(
        left: 20.0, right: 10.0, top: 4.0, bottom: 30.0):const EdgeInsets.only(
        left: 10.0, right: 10.0, top: 4.0, bottom: 30.0);
    
    return new Padding(
      padding: padding,
      child: new InkWell(
        onTap: () {
          print('Card selected');
        },
        child: new Container(
          decoration: new BoxDecoration(
            borderRadius: new BorderRadius.circular(10.0),
            color: Colors.lightGreen,
            boxShadow: [
              new BoxShadow(
                  color: Colors.black.withAlpha(70),
                  offset: const Offset(3.0, 10.0),
                  blurRadius: 15.0)
            ],
            image: new DecorationImage(
              image: new ExactAssetImage(
                  'assets/img_${index%items.length}.jpg'),
              fit: BoxFit.fitHeight,
            ),
          ),
        //                                    height: 200.0,
          width: 200.0,
          child: new Stack(
            children: <Widget>[
              new Align(
                alignment: Alignment.bottomCenter,
                child: new Container(
                    decoration: new BoxDecoration(
                        color: const Color(0xFF273A48),
                        borderRadius: new BorderRadius.only(
                            bottomLeft: new Radius.circular(10.0),
                            bottomRight: new Radius.circular(10.0))),
                    height: 30.0,
                    child: new Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        new Text(
                          '${items[index%items.length]}',
                          style: new TextStyle(color: Colors.white),
                        )
                      ],
                    )),
              )
            ],
          ),
        ),
      ),
    );
  },
  scrollDirection: Axis.horizontal,
  itemCount: items.length,
);

final body = new Scaffold(
  appBar: new AppBar(
    title: new Text(widget.title),
    elevation: 0.0,
    backgroundColor: Colors.transparent,
    actions: <Widget>[
      new IconButton(icon: new Icon(Icons.shopping_cart, color: Colors.white,), onPressed: (){})
    ],
  ),
  backgroundColor: Colors.transparent,
  body: new Container(
    child: new Stack(
      children: <Widget>[
        new Padding(
          padding: new EdgeInsets.only(top: 10.0),
          child: new Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              new Align(
                alignment: Alignment.centerLeft,
                child: new Padding(
                    padding: new EdgeInsets.only(left: 8.0),
                    child: new Text(
                      'Recent Items',
                      style: new TextStyle(color: Colors.white70),
                    )),
              ),
              new Container(
                  height: 300.0, width: _width, child: headerList),
              new Expanded(child:
              ListView.builder(itemBuilder: (context, index) {
                return new ListTile(
                  title: new Column(
                    children: <Widget>[
                      new Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          new Container(
                            height: 72.0,
                            width: 72.0,
                            decoration: new BoxDecoration(
                                color: Colors.lightGreen,
                                boxShadow: [
                                  new BoxShadow(
                                      color:
                                      Colors.black.withAlpha(70),
                                      offset: const Offset(2.0, 2.0),
                                      blurRadius: 2.0)
                                ],
                                borderRadius: new BorderRadius.all(
                                    new Radius.circular(12.0)),
                                image: new DecorationImage(
                                  image: new ExactAssetImage(
                                    'assets/img_${index%items.length}.jpg',
                                  ),
                                  fit: BoxFit.cover,
                                )),
                          ),
                          new SizedBox(
                            width: 8.0,
                          ),
                          new Expanded(
                              child: new Column(
                                mainAxisAlignment:
                                MainAxisAlignment.start,
                                crossAxisAlignment:
                                CrossAxisAlignment.start,
                                children: <Widget>[
                                  new Text(
                                    'My item header',
                                    style: new TextStyle(
                                        fontSize: 14.0,
                                        color: Colors.black87,
                                        fontWeight: FontWeight.bold),
                                  ),
                                  new Text(
                                    'Item Subheader goes here\nLorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry',
                                    style: new TextStyle(
                                        fontSize: 12.0,
                                        color: Colors.black54,
                                        fontWeight: FontWeight.normal),
                                  )
                                ],
                              )),
                          new Icon(
                            Icons.shopping_cart,
                            color: const Color(0xFF273A48),
                          )
                        ],
                      ),
                      new Divider(),
                    ],
                  ),
                );
              }))
            ],
          ),
        ),
      ],
    ),
  ),
);

return new Container(
  decoration: new BoxDecoration(
    color: const Color(0xFF273A48),
  ),
  child: new Stack(
    children: <Widget>[
      new CustomPaint(
        size: new Size(_width, _height),
        painter: new Background(),
        ),
       body,
      ],
    ),
  );
 }
}

这里有一个非常好的例子,包含完整的源代码 Styled list

演示图片


1
哈哈,这比我的答案还要好!感谢你的帮助。 - Jake
如何隐藏一个布局? - griffins

2
这个示例代码展示了一个页面中同时存在两个垂直方向的列表视图,这两个列表视图的数据都来自APIs。我还设计了一个单独的列表项部件或模板(ListItemPosts)。请注意,内容保留HTML标签。
body: ListView(
              children: <Widget>[
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(height: 10.0),
                    new Container(
                      margin: EdgeInsets.only(left: 10.0,right: 10.0),
                      height: 40.0, width: double.infinity,
                      decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(25.0),
                          color: Colors.green.withOpacity(0.25)
                      ),
                    child:Padding(
                      padding: const EdgeInsets.only(left: 15.0,right: 15.0,top: 8.0),


                      child: Text(
                        'Invoiced Products',
                        style: TextStyle(
                            fontFamily: 'Quicksand',
                            fontSize: 20.0,
                            color: Colors.green,
                            fontWeight: FontWeight.bold),
                        textAlign: TextAlign.center,
                      ),
                    ), 
                    ),

                    SizedBox(height: 5.0),
                    FutureBuilder<List<SalesOrder>>(
                      future: fetchstring(http.Client()),
                      builder: (context, snapshot) {
                        if (snapshot.hasError) print(snapshot.error);
                        return snapshot.hasData ? ListItemPosts(
                            items: snapshot.data)
                            : Center(child: CircularProgressIndicator());
                      },
                    ),
                    SizedBox(height: 10.0)
                  ],
                ),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(height: 10.0),
                    new Container(
                      margin: EdgeInsets.only(left:10.0,right: 10.0),
                      height: 40.0, width: double.infinity,
                      decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(25.0),
                          color: Colors.red.withOpacity(0.25)
                      ),
                      child:Padding(
                        padding: const EdgeInsets.only(left: 15.0,right: 15.0,top: 8.0),
                        child: Text(
                          'Pending Products',
                          style: TextStyle(
                              fontFamily: 'Quicksand',
                              fontSize: 20.0,
                              color: Colors.red,
                              fontWeight: FontWeight.bold),
                          textAlign: TextAlign.center,
                        ),
                      ),
                    ),

                    SizedBox(height: 5.0),
                    FutureBuilder<List<SalesOrder>>(
                      future: fetchstring(http.Client()),
                      builder: (context, snapshot) {
                        if (snapshot.hasError) print(snapshot.error);
                        return snapshot.hasData ? ListItemPosts(
                            items: snapshot.data)
                            : Center(child: CircularProgressIndicator());
                      },
                    ),
                    SizedBox(height: 10.0)
                  ],
                )
              ],
            )

列表项发布(小部件)
class ListItemPosts extends StatelessWidget {
  final List<SalesOrder> items;
  ListItemPosts({Key key, this.items}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Container(

        child: new ListView.builder(
            itemCount:  items[0].sodetails.length,
            primary: false,
            shrinkWrap: true,

            itemBuilder: (BuildContext context, int position) {
              return new  Column(
                children: <Widget>[
                  Divider(height: 5.0),
                  listItem(your Data can pass),
                ],
              );


            })

    );

  }

}

Widget listItem(Get the data ) {
  return Container(
    height: 125.0,
    width: double.infinity,

    margin: EdgeInsets.only(left: 10.0,right: 10.0),
    decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(12.0),
      color: Colors.white,
    ),
    child:
    Row(
      children: <Widget>[
        /*Container(
          decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(12.0),
              image:
              DecorationImage(image: AssetImage(imagedata))),
          height: 100.0,
          width: 80.0,
        ),*/

        SizedBox(width: 0.0),
        Container(
          width: MediaQuery.of(context).size.width -30.0,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Flexible(child:
                  Text(
                    imagename,
                    textAlign: TextAlign.left,
                    softWrap: false,
                    style: TextStyle(fontFamily: 'Quicksand',fontSize: 14.0,color: Colors.black),
                  )),
                  SizedBox(height: 5.0),
                  Flexible(child:
                  Text(
                    trim.stringtrim(imagedes),
                    overflow: TextOverflow.ellipsis,
                    maxLines: 2,
                    style: TextStyle(fontFamily: 'Quicksand',fontSize: 12.0,color: Colors.black45),
                  ),
                  ),
                  SizedBox(height: 5.0),
                  Text(
                    'Price: '+Price.toString(),
                    style: TextStyle(fontFamily: 'Quicksand'),
                  ),
                  SizedBox(height: 5.0),
                  Text(
                    'Qty: '+Quatity.toString(),
                    style: TextStyle(fontFamily: 'Quicksand'),
                  ),
                  SizedBox(height: 5.0),
                  Container(
                    height: 2.0,
                    width: 100.0,
                    color: Colors.amber,
                  ),

                ],
              ),

            ],
          ),
        ),

      ],
    ),
  );
}

0

这可能不是最干净的方法,但我对Flutter相对较新,所以这是我能做到的最好的。

首先,我创建了一个主容器来传递所有信息,以便我可以将所有相关代码放在它们各自的位置上,这个部分允许我在同一个容器中显示两个listViews

这是传递给_positonalArguments的一个容器之一。这让我保持元素不会溢出,例如maxHeight: 335.0,是由试错找到的严格参数。

我在传递给_positionalArguments的两个容器中使用了相同的BoxConstraints和相同的margin值。

抱歉我使用图片而不是粘贴代码,因为我正在使用手机上的堆栈来回答这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接