fix: reply listview rebuild

This commit is contained in:
guozhigq
2023-06-21 22:30:54 +08:00
parent 53d873f89b
commit fbe1dfef18
4 changed files with 94 additions and 99 deletions

View File

@ -45,7 +45,7 @@ class VideoReplyController extends GetxController {
if (res['data'].replies.isNotEmpty) { if (res['data'].replies.isNotEmpty) {
currentPage = currentPage + 1; currentPage = currentPage + 1;
noMore.value = '加载中'; noMore.value = '加载中';
if (res['data'].page.count == res['data'].page.acount) { if (replyList.length == res['data'].page.acount) {
noMore.value = '没有更多了'; noMore.value = '没有更多了';
} }
} else { } else {

View File

@ -153,7 +153,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
.bottom), .bottom),
height: height:
MediaQuery.of(context).padding.bottom + MediaQuery.of(context).padding.bottom +
60, 100,
child: Center( child: Center(
child: Obx(() => Text( child: Obx(() => Text(
_videoReplyController.noMore.value)), _videoReplyController.noMore.value)),
@ -219,10 +219,9 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
); );
}, },
).then((value) => { ).then((value) => {
// 完成评论,数据添加 // 完成评论,数据添加
_videoReplyController _videoReplyController.replyList.add(value['data'])
.replyList.add(value['data']) });
});
}, },
tooltip: '发表评论', tooltip: '发表评论',
child: const Icon(Icons.reply), child: const Icon(Icons.reply),

View File

@ -31,7 +31,7 @@ class ReplyItem extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.fromLTRB(12, 2, 8, 0), padding: const EdgeInsets.fromLTRB(12, 4, 8, 2),
child: content(context), child: content(context),
), ),
// Divider( // Divider(
@ -96,18 +96,8 @@ class ReplyItem extends StatelessWidget {
// 'memberAvatar': reply.avatar, // 'memberAvatar': reply.avatar,
// 'heroTag': reply.userName + heroTag, // 'heroTag': reply.userName + heroTag,
// }), // }),
child: Container( child: SizedBox(
width: double.infinity, width: double.infinity,
decoration: BoxDecoration(
image: replyItem!.member!.userSailing!.cardbg != null
? DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
replyItem!.member!.userSailing!.cardbg!['image'],
),
)
: null,
),
child: Stack( child: Stack(
children: [ children: [
Row( Row(
@ -136,12 +126,33 @@ class ReplyItem extends StatelessWidget {
if (replyItem!.isUp!) UpTag(), if (replyItem!.isUp!) UpTag(),
], ],
), ),
Positioned(
top: 0,
left: 0,
right: 0,
child: Container(
width: double.infinity,
height: 45,
decoration: BoxDecoration(
image: replyItem!.member!.userSailing!.cardbg != null
? DecorationImage(
alignment: Alignment.centerRight,
fit: BoxFit.fitHeight,
image: NetworkImage(
replyItem!
.member!.userSailing!.cardbg!['image'],
),
)
: null,
),
),
),
if (replyItem!.member!.userSailing!.cardbg != null && if (replyItem!.member!.userSailing!.cardbg != null &&
replyItem!.member!.userSailing!.cardbg!['fan']['number'] > replyItem!.member!.userSailing!.cardbg!['fan']['number'] >
0) 0)
Positioned( Positioned(
top: 8, top: 10,
left: Get.size.width / 7 * 5.6, left: Get.size.width / 7 * 5.8,
child: DefaultTextStyle( child: DefaultTextStyle(
style: TextStyle( style: TextStyle(
fontFamily: 'fansCard', fontFamily: 'fansCard',
@ -324,19 +335,57 @@ class ReplyItemRow extends StatelessWidget {
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
animationDuration: Duration.zero, animationDuration: Duration.zero,
child: ListView.builder( child: Column(
padding: EdgeInsets.zero, crossAxisAlignment: CrossAxisAlignment.start,
shrinkWrap: true, children: [
physics: const NeverScrollableScrollPhysics(), for (var i = 0; i < replies!.length; i++) ...[
itemCount: replies!.length + extraRow, InkWell(
itemBuilder: (context, index) {
if (extraRow == 1 && index == replies!.length) {
// 有楼中楼回复,在最后显示
return InkWell(
onTap: () => replyReply(replyItem), onTap: () => replyReply(replyItem),
child: Padding( child: Container(
padding: width: double.infinity,
const EdgeInsets.symmetric(vertical: 8, horizontal: 8), padding: EdgeInsets.fromLTRB(
8,
i == 0 && (extraRow == 1 || replies!.length > 1) ? 8 : 5,
8,
5),
child: Text.rich(
overflow: extraRow == 1
? TextOverflow.ellipsis
: TextOverflow.visible,
maxLines: extraRow == 1 ? 2 : null,
TextSpan(
children: [
TextSpan(
text: replies![i].member.uname + ' ',
style: TextStyle(
fontSize: Theme.of(context)
.textTheme
.titleSmall!
.fontSize,
color: Theme.of(context).colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () => {
print('跳转至用户主页'),
},
),
if (replies![i].isUp)
WidgetSpan(
child: UpTag(),
),
buildContent(context, replies![i].content),
],
),
),
),
)
],
if (extraRow == 1)
InkWell(
onTap: () => replyReply(replyItem),
child: Container(
width: double.infinity,
padding: const EdgeInsets.fromLTRB(8, 5, 8, 8),
child: Text.rich( child: Text.rich(
TextSpan( TextSpan(
style: TextStyle( style: TextStyle(
@ -356,51 +405,8 @@ class ReplyItemRow extends StatelessWidget {
), ),
), ),
), ),
); )
} else { ],
return InkWell(
onTap: () => replyReply(replyItem),
child: Padding(
padding: EdgeInsets.fromLTRB(
8,
index == 0 && (extraRow == 1 || replies!.length > 1)
? 8
: 5,
8,
5),
child: Text.rich(
overflow: extraRow == 1
? TextOverflow.ellipsis
: TextOverflow.visible,
maxLines: extraRow == 1 ? 2 : null,
TextSpan(
children: [
TextSpan(
text: replies![index].member.uname + ' ',
style: TextStyle(
fontSize: Theme.of(context)
.textTheme
.titleSmall!
.fontSize,
color: Theme.of(context).colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () => {
print('跳转至用户主页'),
},
),
if (replies![index].isUp)
WidgetSpan(
child: UpTag(),
),
buildContent(context, replies![index].content),
],
),
),
),
);
}
},
), ),
), ),
); );
@ -435,7 +441,7 @@ InlineSpan buildContent(BuildContext context, content) {
if (content.vote.isNotEmpty) { if (content.vote.isNotEmpty) {
content.message.splitMapJoin(RegExp(r"\{vote:.*?\}"), content.message.splitMapJoin(RegExp(r"\{vote:.*?\}"),
onMatch: (Match match) { onMatch: (Match match) {
String matchStr = match[0]!; // String matchStr = match[0]!;
spanChilds.add( spanChilds.add(
TextSpan( TextSpan(
text: '投票: ${content.vote['title']}', text: '投票: ${content.vote['title']}',
@ -462,7 +468,7 @@ InlineSpan buildContent(BuildContext context, content) {
} }
// content.message = content.message.replaceAll(RegExp(r"\{vote:.*?\}"), ' '); // content.message = content.message.replaceAll(RegExp(r"\{vote:.*?\}"), ' ');
// 匹配表情 // 匹配表情
String matchEmote = content.message.splitMapJoin( content.message.splitMapJoin(
RegExp(r"\[.*?\]"), RegExp(r"\[.*?\]"),
onMatch: (Match match) { onMatch: (Match match) {
String matchStr = match[0]!; String matchStr = match[0]!;
@ -669,21 +675,13 @@ InlineSpan buildContent(BuildContext context, content) {
return Container( return Container(
padding: const EdgeInsets.only(top: 6), padding: const EdgeInsets.only(top: 6),
height: height, height: height,
child: GridView( child: GridView.count(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
// 子Item排列规则 crossAxisCount: crossCount.toInt(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( mainAxisSpacing: 4.0,
//横轴元素个数 crossAxisSpacing: 4.0,
crossAxisCount: crossCount.toInt(), childAspectRatio: 1,
//纵轴间距
mainAxisSpacing: 4.0,
//横轴间距
crossAxisSpacing: 4.0,
//子组件宽高长度比例
// childAspectRatio: 1,
),
//GridView中使用的子Widegt
children: list, children: list,
), ),
); );

View File

@ -108,9 +108,8 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
replyLevel: '1', replyLevel: '1',
showReplyRow: false, showReplyRow: false,
addReply: (replyItem) { addReply: (replyItem) {
_videoReplyReplyController.replyList _videoReplyReplyController.replyList.add(replyItem);
.add(replyItem); }),
}),
), ),
SliverToBoxAdapter( SliverToBoxAdapter(
child: Divider( child: Divider(
@ -160,10 +159,9 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
replyLevel: '2', replyLevel: '2',
showReplyRow: false, showReplyRow: false,
addReply: (replyItem) { addReply: (replyItem) {
_videoReplyReplyController _videoReplyReplyController.replyList
.replyList .add(replyItem);
.add(replyItem); }),
}),
); );
} }
}, },