如何处理Listview.sseparated()分隔符的重建和更改分隔符的内容



我有一个ListView,它是一堆新闻文章。新闻文章具有与其相关联的日期,例如March 3March 4

现在,如果文章的日期相同,我希望它们被分组在一起,所以它会变成这样:

March 3

新闻文章1
新闻文章2

March 4

新闻文章3

March 5

新闻文章4
新闻文章5
消息文章6

我试图创建一个跟踪最后一次出现日期的变量:

final _listofuseddates = [];

日期本身是位于此处的Stringdata["date"]

如果文章数据显示的日期不同,则它将插入一个新的分隔符文本,其中包含日期:

ListView.separated(
itemCount: data.length 
itemBuilder: (BuildContext context, int index) {
return NewsItem(
index: index,
data: data[index]
);
},
separatorBuilder: (BuildContext context, int index) {
final _thisdate = data["date"];
if (_listofuseddates.contains(_thedate)) {
return Container();
}
else
{
_listofuseddates.add(_thedate);
return Text(_thedate.toString());
}
},
),

这里发生的事情是将当前文章的日期与我们已经看到的日期列表进行比较,如果这是一个新颖的日期,则会添加一个带有该日期的分隔符文本,例如March 3。如果已经看到日期,则在Container();中不放分隔符,或者至少放一个空的无法察觉的分隔符。

现在,当列表第一次加载时,这是可以的,但一旦滚动列表,所有的内容都会发生变化,所有的日期都会自动删除,因为列表视图正在不断地重建自己,当然日期已经是seen了。更糟糕的是,如果你向下滚动,然后备份列表,那么事情有时会自行逆转,因为第一个看不见的日期是你向上滚动时的最后一个项目。

有没有一种更好的方法来解决这个看似简单的概念,即将日期标题添加到一堆列表项中以保持它们";分组";?

将日期标头放在分隔符中对我来说似乎不是正确的方法。分隔符位于每个列表元素之间,但不在列表的开头或结尾,因此您总是比列表元素少一个分隔符。

我可能会对它进行结构化,使您有一个表示新闻日的小部件,其中包含日期标题和该日期的文章,然后有这些新闻日小部件的列表视图。

大致如下:

import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: TheNewsDemo(),
));
}
class TheNewsDemo extends StatefulWidget {
const TheNewsDemo({Key? key}) : super(key: key);
@override
_TheNewsDemoState createState() => _TheNewsDemoState();
}
class _TheNewsDemoState extends State<TheNewsDemo> {
List<Map<String, dynamic>> theNews = [
{
'day': 'March 3',
'articles': [
'News Article 1',
'News Article 2',
],
},
{
'day': 'March 4',
'articles': [
'News Article 3',
],
},
{
'day': 'March 5',
'articles': [
'News Article 4',
'News Article 5',
'News Article 6',
],
},
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: theNews.length,
itemBuilder: (BuildContext context, int index) {
final element = theNews[index];
return NewsDay(
day: element['day'],
articles: element['articles'],
);
},
),
);
}
}
class NewsDay extends StatelessWidget {
const NewsDay({
Key? key,
required this.day,
required this.articles,
}) : super(key: key);
final String day;
final List<String> articles;
@override
Widget build(BuildContext context) {
return ExpansionTile(
initiallyExpanded: true,
title: Text(day),
children: [
for (final article in articles) NewsItem(article: article),
],
);
}
}
class NewsItem extends StatelessWidget {
const NewsItem({
Key? key,
required this.article,
}) : super(key: key);
final String article;
@override
Widget build(BuildContext context) {
return ListTile(title: Text(article));
}
}

最新更新