在屏幕A中;从 API 响应中,我获取了产品列表(20,000 多个项目)的 JSON 文件 URL。收到 JSON 文件 URL 后,对于后台进程,我使用了隔离和计算,并且我正在对其模型进行更改并将其传递到屏幕 B。
在屏幕 B 中,我简单地使用 Listview.builder (据我所知,它经过优化以在滚动时显示项目)。 我的要求是在 UI 上同时显示所有 20,000 多个项目。我正在执行 sortBy 和 filterBy。
因此,我的用户界面变得非常滞后,有时甚至没有响应。我尝试使用隔离和计算来优化我的 UI 渲染。但我没有成功。
任何人都可以分享他们如何解决的经验或任何参考,这会很有帮助。谢谢
供参考:Flutter Channel 稳定版,3.10.6 Dart SDK 3.0.6
我编写了一个简单的应用程序,它从包含近 20,000 个对象的本地 JSON 中获取数据。它使用
compute
解码 JSON,并使用 ListView.builder 在 UI 滚动时动态渲染每个项目。使用肘来存储项目列表并进行过滤。该应用程序非常稳定,没有任何滞后或问题。您可以在这里查看整个源代码。
class PersonList extends StatelessWidget {
const PersonList({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<PersonCubit, List<Person>>(
builder: (context, items) {
if (items.isEmpty) {
return const Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
prototypeItem: PersonTile(Person.dummy()),
shrinkWrap: true,
itemCount: items.length,
itemBuilder: (_, index) {
return PersonTile(items[index]);
},
);
},
);
}
}
class PersonTile extends StatelessWidget {
const PersonTile(this.p, {super.key});
final Person p;
@override
Widget build(BuildContext context) {
final id = p.id;
final color = int.parse('0xFF${id.substring(id.length - 5, id.length)}');
return Card(
elevation: 0,
child: ListTile(
title: Text(p.name),
subtitle: _Info(balance: p.balance, email: p.email, date: p.registered),
trailing: Icon(
Icons.circle,
color: p.isActive ? Colors.greenAccent : Colors.red,
),
isThreeLine: true,
tileColor: Color(color),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => DetailScreen(p: p)));
},
),
);
}
}
class PersonCubit extends Cubit<List<Person>> {
PersonCubit() : super(const []);
void fetchItems() async {
try {
final s = await rootBundle.loadString('assets/data.json');
final items = await compute(parseItems, s);
emit(items);
} catch (e, st) {
// log
log('Error fetching data!', error: e, stackTrace: st);
emit(const []);
}
}
void sortByDate() {
emit(state.toList()..sort((a, b) => a.registered.compareTo(b.registered)));
}
void sortByName() {
emit(state.toList()..sort((a, b) => a.name.compareTo(b.name)));
}
void sortByBalance() {
emit(state.toList()..sort((a, b) => a.balance.compareTo(b.balance)));
}
}