gpt4 book ai didi

Listview 滚动怪异中的 Flutter Listview

转载 作者:IT王子 更新时间:2023-10-29 07:01:17 24 4
gpt4 key购买 nike

所以我有一个 listview.builder,它使用一个调用另一个 Listview.builder 和另一个 itembuilder 的 itembuilder。我在另一个线程上获得了一些尺寸问题的帮助,一切都很好。该页面的目标是有一个日期分隔符,然后在该日期之前有一个消息列表,它可以根据当天和当天的消息增长。然而,滚动有一些奇怪之处,如果你捕获分隔线,它会上下滚动,但是如果你在分隔线之间加热其中一张卡片,它只会在该区域内滚动。想知道是否有更好的方法来实现相同的布局结果。

任何帮助都会很棒。我将页面中的所有代码放在这里,如果您有任何问题,请告诉我。同样,它一切正常,布局正是我想要的,只是滚动很奇怪而且不是很有效。

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

这是最新的更新代码:

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

最佳答案

如果您可以在您的 ChatWidget 构建中构建日期分隔符,您将会省去很多麻烦:

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'),
],
),
))
],
)

],),
);
}
}

编辑

试试这个:

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

更新

根据每个分隔符的消息数量生成卡片列表,如下所示:

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

更新这是我在 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"),
);
}),
);
}
}

关于Listview 滚动怪异中的 Flutter Listview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47270932/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com