Robert
Robert

Reputation: 5855

Flutter Listview in a Listview scrolling weirdness

So I have a listview.builder that uses an itembuilder that calls another Listview.builder and another itembuilder. I got help on another thread for some sizing issues and everything presents great. The goal of the page is to have a date divider that then has a list of messages by that date, this can grow based on messages for the day and current day. However there is some weirdness to the scolling, if you grab the divider it scrolls fine up and down, however if you hot one of the cards between the divider it only scrolls within that area. Wondered if there was a better way to accomplish the same layout result.

Any help would be great. I put all the code form the page here and let me know if you have questions. Again it all works good and layout is exactly what I want, just scrolls weird and not really effective.

import 'dart:async';
import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cswauthapp/models.dart';
import 'package:cswauthapp/ChatConvoDetail.dart';
import 'package:cswauthapp/Settings.dart' as Admin;
import 'package:cswauthapp/HomePage.dart' as HomePage;
import 'package:cswauthapp/main.dart' as MyHomePage;
import 'package:cswauthapp/PostAuthHome.dart' as PostAuthHome;

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

  static const String routeName = "/ChatNTDate";

  final ChatList mychat;
  final String title;

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

/// // 1. After the page has been created, register it with the app routes
/// routes: <String, WidgetBuilder>{
///   ChatNoThread.routeName: (BuildContext context) => new ChatNoThread(title: "ChatNoThread"),
/// },
///
/// // 2. Then this could be used to navigate to the page.
/// Navigator.pushNamed(context, ChatNoThread.routeName);
///

class _ChatNTDateSepState extends State<ChatNTDateSep> {
  SharedPreferences prefs;
  int oid = 0;
  int pid = 0;
  int authlevel = 0;
  bool admin = false;
  int type = 0;
  String msgid = '';
  List chatlist;
  int listcount = 0;
  bool grpmsg = true;
  String sender = '';
  String receiver = '';
  String message = '';
  String oname = '';
  String pname = '';
  String sendname;
  String receivename;
  String replyto = '';
  String replyfrom = '';
  String replysub = '';
  final TextEditingController _newreplycontroller = new TextEditingController();
  String myfcmtoken = 'NONE';

  _getPrefs() async {
    prefs = await SharedPreferences.getInstance();
    //hasRef = prefs.getBool('hasRef');

    if (mounted) {
      setState(() {
        oid = prefs.getInt('oid');
        pid = prefs.getInt('pid');
        authlevel = prefs.getInt('authlevel');
        admin = prefs.getBool('admin');
        type = 1;
        msgid = widget.mychat.msgkey;
        if (widget.mychat.grpid == '0') {
          grpmsg = false;
        } else {
          grpmsg = true;
        }
        oname = widget.mychat.oname;
        pname = widget.mychat.pname;
        myfcmtoken = prefs.getString('fcmtoken');
        if (authlevel == 0) {
          sender = 'o';
          receiver = 'p';
          sendname = widget.mychat.oname;
          receivename = widget.mychat.pname;
        } else {
          sender = 'p';
          receiver = 'o';
          sendname = widget.mychat.pname;
          receivename = widget.mychat.oname;
        }
        _getChats();
      });
    }
  }

  @override
  void initState() {
    super.initState();
    //controller = new TabController(length: 4, vsync: this);
    _getPrefs();
  }

  var jsonCodec = const JsonCodec();
  var _focusnode = new FocusNode();

  _getChats() async {
    //var _url = 'http://$baseurl/csapi/getmessages/$type/$msgid';
    var _url = 'http://$baseurl/csapi/messages/getdates/$msgid';

    var http = createHttpClient();
    var response = await http.get(_url, headers: getAuthHeader());

    var chats = await jsonCodec.decode(response.body);

    if (mounted) {
      setState(() {
        chatlist = chats.toList();
        listcount = chatlist.length;
        //replysub = 'Re: ' + chatlist[0]['sub'];
      });
    }
  }

  Future<Null> _onRefresh() {
    Completer<Null> completer = new Completer<Null>();
    Timer timer = new Timer(new Duration(seconds: 1), () {
      _getChats();
      completer.complete();
    });
    return completer.future;
  }

  @override
  Widget build(BuildContext context) {

    Widget mytitle;
    if (grpmsg) {
      mytitle = new Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          new Icon(Icons.people),
          new Text('  '),
          new Text(widget.mychat.referralname)
        ],
      );
    } else {
      mytitle = new Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          new Icon(Icons.person),
          new Text('  '),
          new Text(widget.mychat.referralname)
        ],
      );
    }

    /*Widget _grpHdr() {
      assert(grpmsg);
      return new Text(
        widget.mychat.referralname,
        style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
      );
    }

    Widget _noGrpHdr() {
      assert(!grpmsg);
      return new Text(
        widget.mychat.referralname,
        style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
      );
    }*/

    var _children = <Widget>[

      new Expanded(
        child: new RefreshIndicator(
          child: new ListView.builder(
            itemBuilder: _divBuilder,
            itemCount: listcount,shrinkWrap: true,
          ),
          onRefresh: _onRefresh,
        ),
      ),
      new Stack(
        alignment: Alignment.centerRight,
        children: <Widget>[
          new TextField(
            decoration: const InputDecoration(
              hintText: 'Chat Reply',
              labelText: 'Chat Reply:',
            ),
            autofocus: false,
            focusNode: _focusnode,
            maxLines: 2,
            controller: _newreplycontroller,
            keyboardType: TextInputType.url,
          ),
          new IconButton(
            icon: new Icon(Icons.send),
            onPressed: _sendReply,
            alignment: Alignment.centerRight,
          )
        ],
      ),
    ];
    return new Scaffold(
      appBar: new AppBar(
        title: mytitle,
        actions: getAppBarActions(context),
      ),
      body: new Column(
          mainAxisSize: MainAxisSize.min,
          children: _children,
        ),
    );
  }

  Widget _divBuilder(BuildContext context, int index) {
    DateTime getdatediv = getDateDiv(index);
    return new MyChatWidget(
      datediv: getdatediv,
      msgkey: msgid,
    );

  }


  DateTime getDateDiv(int index) {
    DateTime msgdate = DateTime.parse(chatlist[index]['chatdate']).toLocal();
    return msgdate;
  }


  _sendReply() {
    if (_newreplycontroller.text.isEmpty) {
      showDialog(
        context: context,
        child: new AlertDialog(
          content: new Text("Can not submit chat message that is empty"),
          actions: <Widget>[
            new FlatButton(
                child: const Text('OK'),
                onPressed: () {
                  Navigator.pop(context, false);
                }),
            /*new FlatButton(
              child: const Text('SHOW'),
              onPressed: () {
                Navigator.pop(context, true);
              }),*/
          ],
        ),
      );
    } else {

      DateTime dateSubmit = new DateTime.now();
      var mymessage = _newreplycontroller.text;
      ChatMessage mychat = new ChatMessage(
          widget.mychat.msgkey,
          widget.mychat.referralname,
          replysub,
          oid,
          oname,
          pid,
          pname,
          sender,
          sendname,
          receiver,
          receivename,
          mymessage,
          dateSubmit.toString(),
          widget.mychat.grpid,
          widget.mychat.prid,
          myfcmtoken);
      _doSendReply(mychat);
    }
  }

  _doSendReply(mychat) async {

    var json = jsonCodec.encode(mychat);
    var _url = 'http://$baseurl/csapi/sendchatmsg';

    var http = createHttpClient();
    var response = await http.post(_url, body: json, headers: getJSONHeader());

    var chatresp = await jsonCodec.decode(response.body);
    if (chatresp.contains('GOOD')) {
      _getChats();
      _newreplycontroller.text = '';
      _focusnode.unfocus();
      /*Route route = new MaterialPageRoute(
        settings: new RouteSettings(name: "/Chat"),
        builder: (BuildContext context) => new Chat.Chat(title: "Loop Chat Reply"),
      );
      Navigator.of(context).push(route);*/
    } else if (chatresp.contains('EMPTY')){
      showDialog(
        context: context,
        child: new AlertDialog(
          content: new Text("Can not submit chat message that is empty"),
          actions: <Widget>[
            new FlatButton(
                child: const Text('OK'),
                onPressed: () {
                  Navigator.pop(context, false);
                }),
            /*new FlatButton(
              child: const Text('SHOW'),
              onPressed: () {
                Navigator.pop(context, true);
              }),*/
          ],
        ),
      );
    } else {}

  }
}

class MyChatWidget extends StatefulWidget {
  MyChatWidget({Key key, this.datediv, this.msgkey}) : super(key: key);

  final DateTime datediv;
  final String msgkey;

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

class _MyChatWidgetState extends State<MyChatWidget> {
  List messagelist;
  int messagecount = 0;
  var jsonCodec = const JsonCodec();
  var mydate = '';

  _getMessages() async {
    var _url = 'http://$baseurl/csapi/messages/getbydate';
    DateChatMessage dcm = new DateChatMessage(widget.msgkey, widget.datediv.toString());
    var json = jsonCodec.encode(dcm);
    var http = createHttpClient();
    var response = await http.post(_url, headers: getAuthHeader(), body: json);

    var messages = await jsonCodec.decode(response.body);

    if (mounted) {
      setState(() {
        messagelist = messages.toList();
        messagecount = messagelist.length;
        if (new DateFormat.yMd().format(widget.datediv) == new DateFormat.yMd().format(new DateTime.now())) {
          mydate = 'Today';
        } else {
          mydate = new DateFormat.yMMMEd().format(widget.datediv);
        }
        //replysub = 'Re: ' + chatlist[0]['sub'];
      });
    }
  }

  @override
  void initState() {
    super.initState();
    //controller = new TabController(length: 4, vsync: this);
    _getMessages();

  }

  @override
  Widget build(BuildContext context) {
    var _children = <Widget>[
      new Text(mydate, textAlign: TextAlign.left,),
      new Divider(
        height: 5.0,
        color: Colors.grey,
      ),
      //new Text(new DateFormat.yMd().format(widget.datediv),),

      new ListView.builder(
        itemBuilder: _itemBuilder,
        itemCount: messagecount,
        shrinkWrap: true,
      ),

      /*new Flexible(
        child: new ListView.builder(
          itemBuilder: _itemBuilder,
          itemCount: messagecount,
          shrinkWrap: true,
        ),
      ),*/

    ];


    return new Column(
        mainAxisSize: MainAxisSize.min,
        children: _children,
      );
  }

  Widget _itemBuilder(BuildContext context, int index) {
    ChatMessage mychat = getChat(index);
    return new ChatWidget(
      mychat: mychat,
    );
  }

  ChatMessage getChat(int index) {
    //prefs.setInt('pid', myReferralList[index]['pid']);
    return new ChatMessage(
      messagelist[index]['msgkey'],
      messagelist[index]['referralname'],
      messagelist[index]['sub'],
      messagelist[index]['oid'],
      messagelist[index]['oname'],
      messagelist[index]['pid'],
      messagelist[index]['pname'],
      messagelist[index]['sender'],
      messagelist[index]['sendname'],
      messagelist[index]['receiver'],
      messagelist[index]['receivename'],
      messagelist[index]['message'],
      messagelist[index]['submitdate'],
      messagelist[index]['pgrpid'],
      messagelist[index]['prid'],
      messagelist[index]['fcmtoken'],
    );
  }
}


class ChatWidget extends StatefulWidget {
  ChatWidget({Key key, this.mychat}) : super(key: key);

  final ChatMessage mychat;

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

class _ChatWidgetState extends State<ChatWidget> {
  @override
  Widget build(BuildContext context) {
    DateTime submitdate = DateTime.parse(widget.mychat.submitdate).toLocal();

    return new Card(
      child: new Container(
        width: 150.0,
        padding: new EdgeInsets.all(10.0),
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            new Row(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                new Text(
                  widget.mychat.sendname,
                  style: new TextStyle(
                      fontSize: 15.0, fontWeight: FontWeight.bold),
                ),
                new Text(' '),
                new Text(new DateFormat.Hm().format(submitdate)),
                //new Text(submitdate.toLocal().toString())
              ],
            ),

            //new Text(widget.mychat.receivename,style: new TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold),),
            //new Text(new DateFormat.yMd().add_Hm().format(submitdate)),
            new Text('${widget.mychat.message}'),
          ],
        ),
      ),
    );
    /*return new ListTile(
      leading: new CircleAvatar(child: new Text(widget.mychat.oname[0])),
      title: new Text(widget.mychat.referralname),
      subtitle: new Text(new DateFormat.yMd().add_Hm().format(submitdate)),
      trailing: new Text(widget.mychat.sendname),
      onTap: _onTap,
    );*/
  }
}

Here is the latest UPDATED CODE:

import 'dart:async';
import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cswauthapp/models.dart';
import 'package:cswauthapp/ChatConvoDetail.dart';
import 'package:cswauthapp/Settings.dart' as Admin;
import 'package:cswauthapp/HomePage.dart' as HomePage;
import 'package:cswauthapp/main.dart' as MyHomePage;
import 'package:cswauthapp/PostAuthHome.dart' as PostAuthHome;

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

  static const String routeName = "/ChatDivided";

  final ChatList mychat;
  final String title;

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

class _ChatDividedState extends State<ChatDivided> {
  SharedPreferences prefs;
  int oid = 0;
  int pid = 0;
  int authlevel = 0;
  bool admin = false;
  int type = 0;
  String msgid = '';
  List chatlist;
  int listcount = 0;
  bool grpmsg = true;
  String sender = '';
  String receiver = '';
  String message = '';
  String oname = '';
  String pname = '';
  String sendname;
  String receivename;
  String replyto = '';
  String replyfrom = '';
  String replysub = '';
  final TextEditingController _newreplycontroller = new TextEditingController();
  String myfcmtoken = 'NONE';

  _getPrefs() async {
    prefs = await SharedPreferences.getInstance();
    //hasRef = prefs.getBool('hasRef');

    if (mounted) {
      setState(() {
        oid = prefs.getInt('oid');
        pid = prefs.getInt('pid');
        authlevel = prefs.getInt('authlevel');
        admin = prefs.getBool('admin');
        type = 1;
        msgid = widget.mychat.msgkey;
        if (widget.mychat.grpid == '0') {
          grpmsg = false;
        } else {
          grpmsg = true;
        }
        oname = widget.mychat.oname;
        pname = widget.mychat.pname;
        myfcmtoken = prefs.getString('fcmtoken');
        if (authlevel == 0) {
          sender = 'o';
          receiver = 'p';
          sendname = widget.mychat.oname;
          receivename = widget.mychat.pname;
        } else {
          sender = 'p';
          receiver = 'o';
          sendname = widget.mychat.pname;
          receivename = widget.mychat.oname;
        }
        _getChats();
      });
    }
  }

  @override
  void initState() {
    super.initState();
    //controller = new TabController(length: 4, vsync: this);
    _getPrefs();
  }

  var jsonCodec = const JsonCodec();
  var _focusnode = new FocusNode();

  _getChats() async {
    //var _url = 'http://$baseurl/csapi/getmessages/$type/$msgid';
    var _url = 'http://$baseurl/csapi/messages/getdates/$msgid';

    var http = createHttpClient();
    var response = await http.get(_url, headers: getAuthHeader());

    var chats = await jsonCodec.decode(response.body);

    if (mounted) {
      setState(() {
        chatlist = chats.toList();
        listcount = chatlist.length;
        //replysub = 'Re: ' + chatlist[0]['sub'];
      });
    }
  }

  Future<Null> _onRefresh() {
    Completer<Null> completer = new Completer<Null>();
    Timer timer = new Timer(new Duration(seconds: 1), () {
      _getChats();
      completer.complete();
    });
    return completer.future;
  }

  @override
  Widget build(BuildContext context) {

    Widget mytitle;
    if (grpmsg) {
      mytitle = new Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          new Icon(Icons.people),
          new Text('  '),
          new Text(widget.mychat.referralname)
        ],
      );
    } else {
      mytitle = new Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          new Icon(Icons.person),
          new Text('  '),
          new Text(widget.mychat.referralname)
        ],
      );
    }


    return new Scaffold(
      appBar: new AppBar(
        title: mytitle,
        actions: getAppBarActions(context),
      ),
      body: new Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          new Expanded(
            child: new RefreshIndicator(
              child: new ListView.builder(
                itemBuilder: _divBuilder,
                itemCount: listcount,shrinkWrap: true,
              ),
              onRefresh: _onRefresh,
            ),
          ),
          new Stack(
            alignment: Alignment.centerRight,
            children: <Widget>[
              new TextField(
                decoration: const InputDecoration(
                  hintText: 'Chat Reply',
                  labelText: 'Chat Reply:',
                ),
                autofocus: false,
                focusNode: _focusnode,
                maxLines: 2,
                controller: _newreplycontroller,
                keyboardType: TextInputType.url,
              ),
              new IconButton(
                icon: new Icon(Icons.send),
                onPressed: _sendReply,
                alignment: Alignment.centerRight,
              )
            ],
          ),
        ],
      ),
    );
  }


  Widget _divBuilder(BuildContext context, int index) {
    DateTime getdatediv = getDateDiv(index);
    return new MyChatWidget(
      datediv: getdatediv,
      msgkey: msgid,
    );

  }


  DateTime getDateDiv(int index) {
    DateTime msgdate = DateTime.parse(chatlist[index]['chatdate']).toLocal();
    return msgdate;
  }


  _sendReply() {
    if (_newreplycontroller.text.isEmpty) {
      showDialog(
        context: context,
        child: new AlertDialog(
          content: new Text("Can not submit chat message that is empty"),
          actions: <Widget>[
            new FlatButton(
                child: const Text('OK'),
                onPressed: () {
                  Navigator.pop(context, false);
                }),
          ],
        ),
      );
    } else {

      DateTime dateSubmit = new DateTime.now();
      var mymessage = _newreplycontroller.text;
      ChatMessage mychat = new ChatMessage(
          widget.mychat.msgkey,
          widget.mychat.referralname,
          replysub,
          oid,
          oname,
          pid,
          pname,
          sender,
          sendname,
          receiver,
          receivename,
          mymessage,
          dateSubmit.toString(),
          widget.mychat.grpid,
          widget.mychat.prid,
          myfcmtoken);
      _doSendReply(mychat);
    }
  }

  _doSendReply(mychat) async {

    var json = jsonCodec.encode(mychat);
    var _url = 'http://$baseurl/csapi/sendchatmsg';

    var http = createHttpClient();
    var response = await http.post(_url, body: json, headers: getJSONHeader());

    var chatresp = await jsonCodec.decode(response.body);
    if (chatresp.contains('GOOD')) {
      _getChats();
      _newreplycontroller.text = '';
      _focusnode.unfocus();

    } else if (chatresp.contains('EMPTY')){
      showDialog(
        context: context,
        child: new AlertDialog(
          content: new Text("Can not submit chat message that is empty"),
          actions: <Widget>[
            new FlatButton(
                child: const Text('OK'),
                onPressed: () {
                  Navigator.pop(context, false);
                }),

          ],
        ),
      );
    } else {}

  }
}

class MyChatWidget extends StatefulWidget {
  MyChatWidget({Key key, this.datediv, this.msgkey}) : super(key: key);

  final DateTime datediv;
  final String msgkey;

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

class _MyChatWidgetState extends State<MyChatWidget> {
  List messagelist;
  int messagecount = 0;
  var jsonCodec = const JsonCodec();
  var mydate = '';

  _getMessages() async {
    var _url = 'http://$baseurl/csapi/messages/getbydate';
    DateChatMessage dcm = new DateChatMessage(widget.msgkey, widget.datediv.toString());
    var json = jsonCodec.encode(dcm);
    var http = createHttpClient();
    var response = await http.post(_url, headers: getAuthHeader(), body: json);

    var messages = await jsonCodec.decode(response.body);

    if (mounted) {
      setState(() {
        messagelist = messages.toList();
        messagecount = messagelist.length;
        if (new DateFormat.yMd().format(widget.datediv) == new DateFormat.yMd().format(new DateTime.now())) {
          mydate = 'Today';
        } else {
          mydate = new DateFormat.yMMMEd().format(widget.datediv);
        }
        //replysub = 'Re: ' + chatlist[0]['sub'];
      });
    }
  }

  @override
  void initState() {
    super.initState();
    //controller = new TabController(length: 4, vsync: this);
    _getMessages();

  }


  @override
  Widget build(BuildContext context) {
    var _children = [
      new Text(mydate, textAlign: TextAlign.left,),
      new Divider(
        height: 5.0,
        color: Colors.grey,
      ),

      new Flexible(
          child: new Column(
            children: new List.generate(messagecount, (int index) {

              ChatMessage mychat = getChat(index);
              DateTime submitdate = DateTime.parse(mychat.submitdate).toLocal();
              new Card(
                child: new Container(
                  width: 150.0,
                  padding: new EdgeInsets.all(10.0),
                  child: new Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      new Row(
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          new Text(
                            mychat.sendname,
                            style: new TextStyle(
                                fontSize: 15.0, fontWeight: FontWeight.bold),
                          ),
                          new Text(' '),
                          new Text(new DateFormat.Hm().format(submitdate)),

                        ],
                      ),

                      new Text('${mychat.message}'),
                    ],
                  ),
                ),
              );
            }
            ),
          ),
      ),

    ];


    return new Column(
      mainAxisSize: MainAxisSize.min,
      children: _children,
    );
  }

  ChatMessage getChat(int index) {
    //prefs.setInt('pid', myReferralList[index]['pid']);
    return new ChatMessage(
      messagelist[index]['msgkey'],
      messagelist[index]['referralname'],
      messagelist[index]['sub'],
      messagelist[index]['oid'],
      messagelist[index]['oname'],
      messagelist[index]['pid'],
      messagelist[index]['pname'],
      messagelist[index]['sender'],
      messagelist[index]['sendname'],
      messagelist[index]['receiver'],
      messagelist[index]['receivename'],
      messagelist[index]['message'],
      messagelist[index]['submitdate'],
      messagelist[index]['pgrpid'],
      messagelist[index]['prid'],
      messagelist[index]['fcmtoken'],
    );
  }
}

Upvotes: 1

Views: 2724

Answers (1)

Shady Aziza
Shady Aziza

Reputation: 53317

You would save yourself so much trouble if you can build your date divider inside your ChatWidget build:

enter image description here

import 'package:flutter/material.dart';

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(body: new Column(

      children: <Widget>[

        new Flexible (child: new ListView.builder(
            shrinkWrap: true,
            itemCount: 100,
            itemBuilder: (BuildContext context, int index) {
              return new ChatWidget (


              );
            })),
        new Stack(
          alignment: Alignment.centerRight,
          children: <Widget>[
            new TextField(
              decoration: const InputDecoration(
                hintText: 'Chat Reply',
                labelText: 'Chat Reply:',
              ),
              autofocus: false,
              maxLines: 2,
              keyboardType: TextInputType.url,
            ),
            new IconButton(
              icon: new Icon(Icons.send),
              onPressed: null,
              alignment: Alignment.centerRight,
            )
          ],
        ),
      ],
    ));
  }
}

class ChatWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container (child: new Column (children: <Widget>[

      new Divider(height: 15.0, color: Colors.red),
      new Text("My Awesome Date"),
      new Divider(height: 15.0, color: Colors.red),

      new Column(
        children: <Widget>[
          new Card(
              child: new Container(
                padding: new EdgeInsets.all(10.0),
                child: new Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    new Row(
                      children: <Widget>[
                        new Text(
                          "Awesome Child",
                          style: new TextStyle(
                              fontSize: 15.0, fontWeight: FontWeight.bold),
                        ),
                        new Text(' @ '),
                        new Text("Awesome Date"),
                      ],
                    ),

                    new Text(
                        'AWESOMMMMMMMMMMMMMMMMMMMMMMMMMMEEEEEEEEEEEEEEEEEEEEEEEEEEE'),
                  ],
                ),
              ))
        ],
      )

    ],),
    );
  }
}

Edit

Try this:

    Widget _divBuilder(BuildContext context, int index) {
    DateTime getdatediv = getDateDiv(index);
    return new Column(children: <Widget>[new MyChatWidget(
      datediv: getdatediv,
      msgkey: msgid,
    ),
    ],);
  }

Update

Generate a list of cards based on the number of message for each divider like this:

return new Column(
      children: new List.generate(
          5, (int index) { //5 = number of cards per date
        return new Card(
          //layout design
        );
      }),
    );

Update This is a full example of what I meant on List.generate:

enter image description here

import 'package:flutter/material.dart';

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(body: new Column(

      children: <Widget>[

        new Flexible (child: new ListView.builder(
            shrinkWrap: true,
            itemCount: 100,
            itemBuilder: (BuildContext context, int index) {
              return new Column(
                children: <Widget>[
                  new Divider(color: Colors.red,),
                  new Text("Date$index"),
                  new ChatWidget(
                    //pass the number of messages for date[index]
                  )
                ],
              );
            })),
        new Stack(
          alignment: Alignment.centerRight,
          children: <Widget>[
            new TextField(
              decoration: const InputDecoration(
                hintText: 'Chat Reply',
                labelText: 'Chat Reply:',
              ),
              autofocus: false,
              maxLines: 2,
              keyboardType: TextInputType.url,
            ),
            new IconButton(
              icon: new Icon(Icons.send),
              onPressed: null,
              alignment: Alignment.centerRight,
            )
          ],
        ),
      ],
    ));
  }
}

class ChatWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Column(
      children: new List.generate(
          5, (int index) { //5 = number of messages of the current dat[index]
        return new Card(
          //layout design
          child: new Text("Message$index"),
        );
      }),
    );
  }
}

Upvotes: 1

Related Questions