gpt4 book ai didi

dart - 在我的 ListView 中 flutter 刷新数据

转载 作者:行者123 更新时间:2023-12-03 02:53:35 25 4
gpt4 key购买 nike

更新这是 StreamBuilder 代码:我目前正在尝试使用运行 Stream.fromFuture 的计时器进行更新,该计时器会更新数据,但会出现闪烁和滚动怪异现象。

new StreamBuilder(
initialData: myInitialData,
stream: msgstream,
builder: (BuildContext context, AsyncSnapshot<List<Map>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return new Text('Waiting to start');
case ConnectionState.waiting:
return new Text('');
default:
if (snapshot.hasError) {
return new Text('Error: ${snapshot.error}');
} else {
myInitialData = snapshot.data;
return new RefreshIndicator(
child: new ListView.builder(
itemBuilder: (context, index) {
Stream<List<Map>> msgstream2;
Future<List<Map>> _responseDate = ChatDB.instance.getMessagesByDate(snapshot.data[index]['msgkey'], snapshot.data[index]['msgdate']);
msgstream2 = new Stream.fromFuture(_responseDate);
return new StreamBuilder(
initialData: myInitialData2,
stream: msgstream2,
builder: (BuildContext context, AsyncSnapshot<List<Map>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return new Text('Waiting to start');
case ConnectionState.waiting:
return new Text('');
default:
List messList;
var mybytes;
File myimageview;
Image newimageview;
String imgStr;
String vidStr;
String vidimgstr;
myInitialData2 = snapshot.data;
List<dynamic> json = snapshot.data;
List messagelist = [];
json.forEach((element) {

DateTime submitdate =
DateTime.parse(element['submitdate']).toLocal();
String myvideo = (element['chatvideo']);
String myimage = element['chatimage'];
String myvideoimage = element['chatvideoimage'];
File imgfile;
File vidfile;
File vidimgfile;
bool vidInit = false;
Future<Null> _launched;
String localAssetPath;
String localVideoPath;
String mymessage = element['message'].replaceAll("[\u2018\u2019]", "'");
//print('MYDATE: '+submitdate.toString());
_checkFile(File file) async {
var checkfile = await file.exists();
print('VIDEXISTS: '+checkfile.toString());
}
Future<Null> _launchVideo(String url, bool isLocal) async {
if (await canLaunchVideo(url, isLocal)) {
await launchVideo(url, isLocal);
} else {
throw 'Could not launch $url';
}
}
void _launchLocal() =>
setState(() => _launched = _launchVideo(localVideoPath, true)
);

Widget _showVideo() {
return new Flexible(
child: new Card(
child: new Column(
children: <Widget>[
new ListTile(subtitle: new Text('Video'), title: new Text(element['referralname']),),
new GestureDetector(
onTap: _launchLocal,
child: new Image.file(
vidimgfile,
width: 150.0,
),
),
],
),
)
);
}

if (myimage != "") {
imgStr = element['chatimage'];
imgfile = new File(imgStr);
}
if (myvideo != "") {
vidStr = element['chatvideo'];
vidimgstr = element['chatvideoimage'];
vidimgfile = new File(vidimgstr);

localVideoPath = '$vidStr';


}

_showLgPic() {
Route route = new MaterialPageRoute(
settings: new RouteSettings(name: "/ShowPic"),
builder: (BuildContext context) => new ShowPic(
image: imgfile,
),
);
Navigator.of(context).push(route);
}

Widget _showGraphic() {
Widget mywidget;
if (myimage != "") {
mywidget = new GestureDetector(
child: new Image.file(
imgfile,
width: 300.0,
),
onTap: _showLgPic,
);
} else if (myvideo != "") {
mywidget = _showVideo();
} else {
mywidget = new Container();
}
return mywidget;
}

messagelist.add(
new Container(
//width: 300.0,
padding: new EdgeInsets.all(10.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Container(
padding: new EdgeInsets.only(bottom: 5.0),
child: new Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new CircleAvatar(
child: new Text(
element['sendname'][0],
style: new TextStyle(fontSize: 15.0),
),
radius: 12.0,
),
new Text(' '),
new Text(
element['sendname'],
style: new TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
new Text(' '),
new Text(
new DateFormat.Hm().format(submitdate),
style: new TextStyle(
color: Colors.grey, fontSize: 12.0),
),

],
),
),
new Row(
children: <Widget>[
new Text(' '),
new Flexible(
child: new Text(mymessage),
)
],
),
new Container(
width: 150.0,
child: new Row(
children: <Widget>[
new Text(' '),
_showGraphic()
],
)),
],
),
),
);
});
return new Column(children: messagelist);
}
}
);
/*return new MyChatWidget(
datediv: snapshot.data[index]['msgdate'],
msgkey: snapshot.data[index]['msgkey'],
);*/

},
//itemBuilder: _itemBuilder,
controller: _scrollController,
reverse: true,
itemCount: snapshot.data.length,
),
onRefresh: _onRefresh
);
}

}
}),

我从本地 sqlite 数据库的 Future> 开始。我利用那个 future 并使用数据从数据库中获取另一个 Future>。我使用 Listview.builder 构建小部件等......一切都很好,但需要在消息进入时实时刷新数据并在数据库中更新。我将 futures 转换为流并使用计时器去获取新数据,但是我的屏幕当然会闪烁,尽管数据会刷新它的丑陋。

所以我想找出一种更好的方法来更新数据而不会出现闪烁,并且如果用户在页面上滚动查看消息则不会影响他们。

我目前使用 2 个 future,因为其中一个用于在每个日期的消息之间构建日期分隔符。我一直在寻找 StreamController 并订阅它,但不清楚如何更新 Controller 中的数据,因为数据在到达页面时需要完整,然后在新消息同步时添加。

所以我一直在寻找我发现的类似这样的东西:

class Server {
StreamController<List<Map>> _controller = new StreamController.broadcast();
void addMessage(int message) {
var newmsg = await database.rawQuery('select c.*, date(submitdate, "localtime") as msgtime from v_groupchats g join chats c on c.id = g.id where (oid = $oid or prid = $prid) and c.msgkey not in (select msgkey from chatArchive) order by submitdate desc');
_controller.add(message);
}
Stream get messages => _controller.stream;
}

这还不完整,只是希望它能帮助对我有一些想法的人。

在此先感谢您的帮助。

最佳答案

这种闪烁很可能是您的结果:

case ConnectionState.waiting:
return new Text('');

因为每次获取数据时,您的流都会在 ConnectionState.done 之前进入一个短暂的 ConnectionState.waiting 时刻。您所做的是告诉 UI 在每次获取数据时基本上不显示任何 Text('')。即使只需要 50 毫秒,这对人眼来说也是显而易见的......

因此,如果您不关心您的流正在获取数据,那么请删除该检查。否则,您可以将您的布局更改为 Stack 并在某处覆盖加载动画,或者只是表明它当前正在获取数据的东西。

(请注意,当我尝试使用模拟的 Future.delayed(const Duration(milliseconds: 50), () => data) 测试您的设置时,我能够看到这种闪烁)we can perceive quicker still )

关于dart - 在我的 ListView 中 flutter 刷新数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49050896/

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