- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
所以我有一个 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
构建中构建日期分隔符,您将会省去很多麻烦:
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
中的意思的完整示例:
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/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!