gpt4 book ai didi

flutter - 在 ListView 上构建期间调用 setState() 或 markNeedsBuild()

转载 作者:行者123 更新时间:2023-12-03 18:34:58 25 4
gpt4 key购买 nike

所以我试图重构我的 listView 逻辑。基本上我的 ListView 在 UI 逻辑上变得很麻烦,所以我决定,为什么不将 UI 逻辑的某些部分移到另一个类中

这是我的代码
ListPage.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:sample_flutter_works/ListTextArea.dart';
import 'package:sample_flutter_works/Model.dart';
import 'dart:convert';
import 'package:sample_flutter_works/RefreshTableContainer.dart';

class ListPage extends StatefulWidget {
@override
MyListPage createState() => MyListPage();
}

class MyListPage extends State<ListPage> {
MessageList messageList;
List<int> viewTimeInfo;
ScrollController _controller;

_scrollListener() {

}

@override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);

_controller = ScrollController();
_controller.addListener(_scrollListener);

loadMessages(
completionBlock: (dataSet) => {
setState(() {
messageList = dataSet;
})
});
}

void loadMessages({completionBlock}) async {
var jsonString = await rootBundle.loadString('assets/Chat.json');
final jsonResponse = json.decode(jsonString);
if (jsonResponse != null) {
completionBlock(MessageList.fromJSON(jsonResponse));
} else {
completionBlock(null);
}
}

Widget listLayout() {
return ListView.separated(
padding: const EdgeInsets.all(8.0),
itemCount: (messageList != null && messageList.msgList != null)
? messageList.msgList.length
: 0,
separatorBuilder: (context, index) => Divider(
color: Colors.black,
height: 4.0,
),
itemBuilder: (BuildContext context, int index) {
var msgValToSend =
(messageList != null && messageList.msgList != null)
? messageList.msgList[index]
: null;

return Stack(
children: <Widget>[
IntrinsicHeight(
child: Row(
children: <Widget>[
getTheImageLayout(msgValToSend),
new ListTextArea(
msg: msgValToSend,
didTapOnTextArea: tappedOnTextArea,
visibilityCheck: checkForVisibility)
],
),
)
],
);
});
}


tappedOnTextArea(Message msg) {
var viewedInfo = this.viewTimeInfo;
if (viewedInfo != null) {
var indexOfTappedElement = viewedInfo.indexOf(msg.messageID);

if (indexOfTappedElement != null && indexOfTappedElement != -1) {
viewedInfo.removeAt(indexOfTappedElement);
} else {
viewedInfo.add(msg.messageID);
}
} else {
viewedInfo = [msg.messageID];
}

setState(() {
viewTimeInfo = viewedInfo;
});
}

checkForVisibility(bool _visible, Message msg) {
if (msg != null && this.viewTimeInfo != null) {
var checkForIndex = this.viewTimeInfo.indexOf(msg.messageID);
if (checkForIndex != null && checkForIndex != -1) {
_visible = true;
}
}
}


Widget getTheImageLayout(Message msg) {
return Expanded(
flex: 2,
child: Align(
alignment: Alignment.topLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(5, 2.5, 0, 0),
child: Container(
color: Colors.red,
height: 50,
child: Row(
children: <Widget>[
userImageView(msg),
],
)),
)));
}

Widget userImageView(Message msg) {
return Expanded(
flex: 8,
child: Align(
alignment: Alignment.centerLeft,
child: Container(
width: 40.0,
height: 40.0,
decoration:
BoxDecoration(shape: BoxShape.circle, color: Colors.green),
child: ClipOval(
child: Image.network(
(msg.msgUser.userPicUrl != null)
? msg.msgUser.userPicUrl
: 'https://picsum.photos/250?image=9',
fit: BoxFit.fill,
),
))));
}

Future<void> refreshTheChatTable() async {
print(" This is where the logic of pulll 2 refresh must be written ");

loadMessages(
completionBlock: (dataSet) => {
setState(() {
messageList = dataSet;
})
});
}

@override
Widget build(BuildContext context) {
return new RefreshTableContainer(
listLayout: listLayout(),
pull2RefreshAction: refreshTheChatTable,
);
}
}

ListTextArea.dart
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:sample_flutter_works/Model.dart';

class ListTextArea extends StatelessWidget {

Message msg;
Function didTapOnTextArea;
Function visibilityCheck;

ListTextArea({
this.msg,
this.didTapOnTextArea,
this.visibilityCheck
});

@override
Widget build(BuildContext context) {
return Expanded(
flex: 8,
child: GestureDetector(
onTap: didTapOnTextArea(msg),
child: Padding(
padding: EdgeInsets.fromLTRB(0, 2.5, 10, 0),
child: Column(
children: getChildWidgetArray(msg) ,
),
),
));
}

List<Widget> getChildWidgetArray(Message msg) {

var elementalArray = [
Align(
alignment: Alignment.topLeft,
child: Text(
(msg != null) ? msg.msgContent.content : "Data Loading",
style: TextStyle(
background: Paint()..color = Colors.orange,
),
),
),
Spacer(), // Defaults to a flex of one.
Align(
alignment: Alignment.bottomRight,
child: Text(
'Date of sending',
textDirection: TextDirection.rtl,
style: TextStyle(
background: Paint()..color = Colors.blue,
),
),
)
];

var _visible = false;
visibilityCheck(_visible,msg);

var timeInfo = AnimatedOpacity (
opacity: _visible ? 1.0 : 0.0,
duration: Duration(milliseconds: 500),
child: Align(
child: _visible ? (Align(alignment: Alignment.topLeft,child:Column(children: <Widget>[Text("Last Read :" + (msg.msgTimeInfo.lastReadInfo)),
Text("Delievered :" + (msg.msgTimeInfo.deliveredInfo))],))): null));
elementalArray.add(timeInfo);

return elementalArray;
}
}

错误如下:
enter image description here

我正在尝试做的(或者在整个代码在 ListPage.dart 中之前已经做过)是在 listView 中动态计算单元格,每个单元格响应显示更多数据的点击操作。我根本不明白我在这里做错了什么。

我在 init 中调用了 setState 但在回调函数中。 statelesswidget ListTextArea 根本不会处理状态,而是将 tapAction 返回给 StateFulWidget ListPage.dart。

那么为什么我会收到此错误。任何见解都会有所帮助。

最佳答案

就我而言,在构建完成之前设置状态时发生了错误,因此,我将其推迟到下一个滴答声并且它起作用了。
之前

myFunction()
新的
Future.delayed(Duration.zero, () async {
myFunction();
});

关于flutter - 在 ListView 上构建期间调用 setState() 或 markNeedsBuild(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57377394/

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