Deb*_*rty 5 flutter statelesswidget flutter-layout
所以我试图重构我的 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,
);
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试做的(或者在整个代码在 ListPage.dart 中之前已经做过)是在 listView 中动态计算单元格,每个单元格响应显示更多数据的点击操作。我根本不明白我在这里做错了什么。
我在 init 中调用了 setState 但在回调函数中。statelesswidget ListTextArea 根本不会处理状态,而是将 tapAction 返回给 StateFulWidget ListPage.dart。
那么为什么我会收到此错误。任何见解都会有所帮助。
就我而言,在构建完成之前设置状态时发生了错误,因此,我将其推迟到下一个滴答声并且它起作用了。
之前
myFunction()
Run Code Online (Sandbox Code Playgroud)
新的
Future.delayed(Duration.zero, () async {
myFunction();
});
Run Code Online (Sandbox Code Playgroud)
问题出在 ListTextArea.dart 行
onTap: didTapOnTextArea(msg),
Run Code Online (Sandbox Code Playgroud)
您didTapOnTextArea在构建方法中调用函数,而不是将其作为点击侦听器传递。你必须用它替换它
onTap: (){
didTapOnTextArea(msg);
},
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8282 次 |
| 最近记录: |