web-dev-qa-db-fra.com

Lister les groupes de vues avec séparateur

Je cherche des conseils pour créer des listes de vues avec des séparateurs. Par exemple, je voudrais prendre les messages d'une base de données groupée par date et séparer les messages par date avec un graphique ou une ligne, etc., puis placer les messages sous le séparateur. Il serait souhaitable d’essayer cela dans le flutter et tout guidage ou Pousser dans la bonne direction.

7
Robert

Je m'excuse pour la laideur du design, mais juste pour vous montrer que vous pouvez très bien construire votre propre design que vous désirez, voici un exemple rapide:

 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: () {})
            ],
          )
        ],
      ),
    );
  }
}

Pour une meilleure conception, vous pouvez supprimer les bordures et utiliser plutôt une 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,),
            ],
          )
        ],
      ),

Et une meilleure solution visuelle à mon avis est d’utiliser une Card au lieu de 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,),
            ],
          )
        ],
      ),
    );
12
aziza

mettez simplement la ListItem dans une Container et ajoutez une décoration:

  @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()
                )
            )
        );
  }
12
BoygeniusDexter

Bien que cela ne soit pas applicable à votre situation, un moyen simple d’ajouter des séparateurs à un ListView consiste à utiliser 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;
  }
}

MODIFIER:

ListTile.divideTiles n'est pas le bon choix pour les listes construites de manière dynamique. L'ajout d'un diviseur au stade où l'élément de liste est créé est probablement la meilleure voie à suivre:

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')));
  }
}
3
Matt S.

Une solution beaucoup plus propre et simple consisterait à utiliser les méthodes suivantes

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")),
      ),
)
2
Nudge
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);

Le code productListAdapter est ici

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),
       ),
     );
   }
 }
0