使用分隔符的颤振组列表视图

时间:2017-11-11 00:49:14

标签: flutter

我正在寻找使用分隔符创建列表视图的一些指导。例如,我想从按日期分组的数据库中获取消息,并按日期将消息与某些图形或行等分开......然后在分隔符下面显示消息。尝试这一点,任何指导或推动正确的方向,将不胜感激。

7 个答案:

答案 0 :(得分:14)

我为设计的丑陋道歉,但为了向您展示,您可以构建自己想要的设计,这是一个简单的例子:

enter image description here

import "package:flutter/material.dart";
import 'package:meta/meta.dart';

class Test extends StatefulWidget {
  @override
  _TestState createState() => new _TestState();
}

class _TestState extends State<Test> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Test"),
      ),
      body: new ListView.builder(
        // itemCount: myData.lenght(),
          itemCount: 20,
          itemBuilder: (BuildContext context, int index) {
            //sort my data by timestamp before building
            return new CustomWidget(date: "Convert my time stamp to date",
              content: "My Awesome Content",
              trailingIconOne: new Icon(Icons.share, color: Colors.blueAccent,),
              trailingIconTwo: new Icon(
                Icons.favorite, color: Colors.redAccent,),);
          }),
    );
  }
}

class CustomWidget extends StatelessWidget {
  String date;
  String content;

  Icon trailingIconOne;

  Icon trailingIconTwo;

  CustomWidget(
      {@required this.date, @required this.content, @required this.trailingIconOne, @required this.trailingIconTwo});

  @override
  Widget build(BuildContext context) {
    return new Container(
      decoration: new BoxDecoration(
          border: new Border.all(color: Colors.grey[500])
      ),
      child: new Column(
        children: <Widget>[
          new Container (child: new Text(date), color: Colors.yellow[200],),
          new Container(height: 15.0,),
          new Text(content),
          new Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              new IconButton(icon: trailingIconOne, onPressed: () {}),
              new Container(width: 10.0,),
              new IconButton(icon: trailingIconTwo, onPressed: () {})
            ],
          )
        ],
      ),
    );
  }
}

为了更好的设计,您可以摆脱边框并改为使用Divider

return new Container(
      child: new Column(
        children: <Widget>[
          new Column (children: <Widget>[
            new Container (child: new Text(date), color: Colors.yellow[200],),
            new Container(height: 15.0,),
            new Text(content),
            new Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                new IconButton(icon: trailingIconOne, onPressed: () {}),
                new Container(width: 10.0,),
                new IconButton(icon: trailingIconTwo, onPressed: () {}),
          ], ),

              new Divider(height: 15.0,color: Colors.red,),
            ],
          )
        ],
      ),

我认为更好的视觉解决方案是使用Card代替Container

return new Card(
      child: new Column(
        children: <Widget>[
          new Column (children: <Widget>[
            new Container (child: new Text(date), color: Colors.yellow[200],),
            new Container(height: 15.0,),
            new Text(content),
            new Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                new IconButton(icon: trailingIconOne, onPressed: () {}),
                new Container(width: 10.0,),
                new IconButton(icon: trailingIconTwo, onPressed: () {}),
          ], ),

            //  new Divider(height: 15.0,color: Colors.red,),
            ],
          )
        ],
      ),
    );

答案 1 :(得分:13)

只需将ListItem放入Container并添加装饰:

  @override
  Widget build(BuildContext context) {
    return new Container(
        child: new ListTile(
          title: new Text('I have border')
        ),
        decoration:
            new BoxDecoration(
                border: new Border(
                    bottom: new BorderSide()
                )
            )
        );
  }

答案 2 :(得分:7)

更干净,更简单的解决方案是使用以下内容

ListView.separated(
  separatorBuilder: (context, index) => Divider(
        color: Colors.black,
      ),
  itemCount: 20,
  itemBuilder: (context, index) => Padding(
        padding: EdgeInsets.all(8.0),
        child: Center(child: Text("Index $index")),
      ),
)

答案 3 :(得分:3)

虽然这可能不适用于您的情况,但将分隔符添加到ListView的简单方法是使用ListView.divideTiles

// Adapted from https://flutter.io/flutter-for-android/#listviews--adapters

import 'package:flutter/material.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,
      ),
      home: new ListExamplePage(),
    );
  }
}

class ListExamplePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // https://docs.flutter.io/flutter/material/ListTile/divideTiles.html
    var dividedWidgetList = ListTile.divideTiles(
        context: context,
        tiles: _getListData(),
        color: Colors.black).toList();

    return new Scaffold(
      appBar: new AppBar(
        title: new Text('List Example'),
      ),
      body: new ListView(children: dividedWidgetList)
    );
  }

  _getListData() {
    List<Widget> widgets = [];
    for (int i=0; i<100; i++) {
      widgets.add(
        new Padding(
            padding: new EdgeInsets.all(10.0),
            child: new Text('Row $i'))
      );
    }
    return widgets;
  }
}

编辑:

对于动态构建的列表,ListTile.divideTiles不是正确的选择。在构建列表项的阶段添加分隔符可能是最好的方法:

import 'package:flutter/material.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,
      ),
      home: new ListExamplePage(),
    );
  }
}

class ListExamplePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text('List Example'),
        ),
        body: new ListView.builder(
          itemBuilder: (BuildContext context, int position) =>
              // Try using either _getRowWithDivider or _getRowWithBoxDecoration
              // for two different ways of rendering a divider
              _getRowWithDivider(position),
        ));
  }

  /// Returns the widget at position i in the list, separated using a divider
  Widget _getRowWithDivider(int i) {
    var children = <Widget>[
      new Padding(padding: new EdgeInsets.all(10.0), child: new Text('Row $i')),
      new Divider(height: 5.0),
    ];

    return new Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: children,
    );
  }

// Returns the widget at position i in the list, separated using a BoxDecoration
  Widget _getRowWithBoxDecoration(int i) {
    return new Container(
        decoration: new BoxDecoration(
            border:
                new Border(bottom: new BorderSide(color: Colors.grey[100]))),
        child: new Padding(
            padding: new EdgeInsets.all(10.0), child: new Text('Row $i')));
  }
}

答案 4 :(得分:1)

很多过于复杂的答案

只需使用divideTiles:

new ListView(
              children: ListTile.divideTiles(context: context, tiles:

或者使用分隔符:

new ListView.separated(
              itemCount: 25,
              separatorBuilder: (BuildContext context, int index) => Divider(),
              itemBuilder: (BuildContext context, int index) {

答案 5 :(得分:0)

final Iterable<ListTile> products = widget.products.map((Product product) {
  return productListAdapter(
    product: product,
  ).build(context);
});

final listView = ListTile.divideTiles(
        context: context, tiles: products, color: Colors.black12)
    .toList();

return ListView(
    padding: EdgeInsets.symmetric(vertical: 8.0), children: listView);

productListAdapter代码在此处

class productListAdapter extends StatelessWidget {
   final Product product;  
   productListAdapter({this.product});

   TextStyle getTextStyle() {
       return TextStyle(
           fontSize: 16.0,
           color: Colors.black);
   }

   Color getColor(BuildContext context) {
       return Theme.of(context).primaryColor;
     }
   }

   @override
   Widget build(BuildContext context) {
     return ListTile(
       title: Text(product.name),
       leading: CircleAvatar(
         child: Text(
           product.name[0],
           style: getTextStyle(),
         ),
         backgroundColor: getColor(context),
       ),
     );
   }
 }

答案 6 :(得分:0)

简短回答长

只需使用Column并添加Divider

ListView.builder(
      itemCount: count,
      itemBuilder: (context, int index) {return tile(index);},
    ),

为itemBuilder创建小部件

Widget tile(int index) {
return Column(
  children: <Widget>[
    // your widgets in listView
    Divider(),    //at last simply add divider
  ],
);

}