Fllutter ListView尽管数据列表已更新,除非我一直滚动到End deend

问题描述 投票:0回答:1
class SearchPostsFilter with SearchProviderService { final formatTimestamp = FormatDate(); void filterPostsToBest() { final sortedVents = searchPostsProvider.vents .toList() ..sort((a, b) => a.totalLikes.compareTo(b.totalLikes)); searchPostsProvider.setVents(sortedVents); } void filterPostsToLatest() { final sortedVents = searchPostsProvider.vents .toList() ..sort((a, b) => formatTimestamp.parseFormattedTimestamp(b.postTimestamp) .compareTo(formatTimestamp.parseFormattedTimestamp(a.postTimestamp))); searchPostsProvider.setVents(sortedVents); } void filterPostsToOldest() { final sortedVents = searchPostsProvider.vents .toList() ..sort((a, b) => formatTimestamp.parseFormattedTimestamp(a.postTimestamp) .compareTo(formatTimestamp.parseFormattedTimestamp(b.postTimestamp))); searchPostsProvider.setVents(sortedVents); } void filterToControversial() { final sortedVents = searchPostsProvider.vents .where((post) => post.totalComments >= post.totalLikes) .toList(); searchPostsProvider.setVents(sortedVents); } }

存储帖子信息的提供商/数据类:

class SearchVents { String title; String creator; String postTimestamp; Uint8List profilePic; int totalLikes; int totalComments; bool isPostLiked; bool isPostSaved; SearchVents({ required this.title, required this.creator, required this.postTimestamp, required this.profilePic, this.totalLikes = 0, this.totalComments = 0, this.isPostLiked = false, this.isPostSaved = false }); } class SearchPostsProvider extends ChangeNotifier { List<SearchVents> _vents = []; List<SearchVents> get vents => _vents; void setVents(List<SearchVents> vents) { _vents = vents; notifyListeners(); } }
帖子listView:

class SearchPostsListView extends StatefulWidget { const SearchPostsListView({super.key}); @override State<SearchPostsListView> createState() => _SearchPostsListViewState(); } class _SearchPostsListViewState extends State<SearchPostsListView> { final sortOptionsNotifier = ValueNotifier<String>('Best'); final searchPostsFilter = SearchPostsFilter(); Widget _buildVentPreview(SearchVents ventData) { return Padding( padding: const EdgeInsets.only(bottom: 8.5), child: DefaultVentPreviewer( title: ventData.title, bodyText: '', creator: ventData.creator, postTimestamp: ventData.postTimestamp, totalLikes: ventData.totalLikes, totalComments: ventData.totalComments, pfpData: ventData.profilePic, useV2ActionButtons: true, ), ); } void _sortOptionsOnPressed({required String filter}) { switch (filter) { case == 'Best': searchPostsFilter.filterPostsToBest(); break; case == 'Latest': searchPostsFilter.filterPostsToLatest(); break; case == 'Oldest': searchPostsFilter.filterPostsToOldest(); break; case == 'Controversial': searchPostsFilter.filterToControversial(); break; } sortOptionsNotifier.value = filter; Navigator.pop(context); } Widget _buildFilterButtons({ required ValueListenable notifier, required VoidCallback onPressed }) { return SizedBox( height: 35, child: InkWellEffect( onPressed: onPressed, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const SizedBox(width: 8), const Icon(CupertinoIcons.chevron_down, color: ThemeColor.thirdWhite, size: 15), const SizedBox(width: 8), ValueListenableBuilder( valueListenable: notifier, builder: (_, filterText, __) { return Text( filterText, style: GoogleFonts.inter( color: ThemeColor.thirdWhite, fontWeight: FontWeight.w800, fontSize: 13 ) ); }, ), const SizedBox(width: 8), ], ), ), ); } Widget _buildListView(List<SearchVents> ventDataList) { return DynamicHeightGridView( physics: const AlwaysScrollableScrollPhysics( parent: BouncingScrollPhysics(), ), crossAxisCount: 1, itemCount: ventDataList.length + 1, builder: (_, index) { if (index == 0) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 12), Row( children: [ _buildFilterButtons( notifier: sortOptionsNotifier, onPressed: () { BottomsheetSearchFilter().buildSortOptionsBottomsheet( context: context, currentFilter: sortOptionsNotifier.value, bestOnPressed: () => _sortOptionsOnPressed(filter: 'Best'), latestOnPressed: () => _sortOptionsOnPressed(filter: 'Latest'), oldestOnPressed: () => _sortOptionsOnPressed(filter: 'Oldest'), controversialOnPressed: () => _sortOptionsOnPressed(filter: 'Controversial'), ); } ), ], ), const SizedBox(height: 4), ], ); } final reversedVentIndex = ventDataList.length - index; if (reversedVentIndex >= 0) { final vents = ventDataList[reversedVentIndex]; return _buildVentPreview(vents); } return const SizedBox.shrink(); }, ); } @override void dispose() { sortOptionsNotifier.dispose(); super.dispose(); } @override void initState() { super.initState(); searchPostsFilter.filterPostsToBest(); } @override Widget build(BuildContext context) { return Consumer<SearchPostsProvider>( builder: (_, ventData, __) { final ventDataList = ventData.vents; return _buildListView(ventDataList); } ); } }
现在,即使列表视图未正确排序,也要牢记,当我打印数据列表时,它可以准确地显示了如何对其进行排序,但不会反映在listView。
void filterPostsToOldest() { final sortedVents = searchPostsProvider.vents .toList() ..sort((a, b) => formatTimestamp.parseFormattedTimestamp(a.postTimestamp) .compareTo(formatTimestamp.parseFormattedTimestamp(b.postTimestamp))); for(var post in sortedVents) { print('${post.title} / ${post.postTimestamp}'); } searchPostsProvider.setVents(sortedVents); }

因此,我尝试在listView上使用keyedSubtree,如Chatgpt所建议,但它不起作用,没有任何更改
return KeyedSubtree(
        key: ValueKey('${vents.title}/${vents.creator}'),
              child: _buildVentPreview(vents),
       );

Tldr; ListView与列表数据不正确匹配。
	

您不需要键控子树,您只需在返回的列中添加一个

UniqueKey
即可。一个键将识别列表视图中的每个元素,因此当您重新排列它们时,它们正确识别了,因此您必须在子树中的最顶部添加键,在这种情况下,对于每个视图卡成为
builder

,所以只要给它一个

Column
flutter listview provider
1个回答
0
投票
如果您想更多地了解它,可以检查this视频

    

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.