flutter - 为什么 context.select 只在 ListView.builder 包含在列中时更新 UI
问题描述
删除 ListView.builder 后,context.select
不会更新 Ui。想知道为什么会这样。
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => ListProvider(),
),
ChangeNotifierProxyProvider<ListProvider, ListReceiver>(
create: (context) => ListReceiver(),
update: (_, listProvider, listReceiver) =>
listReceiver..displayList(listProvider.firstList),
)
],
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/': (context) => FirstPage(),
},
),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('This is a ProxyProvider test'),
),
body: Builder(
builder: (context) => Column(
children: [
ElevatedButton(
onPressed: () {
context.read<ListProvider>().addToList();
},
child: Text('add to list'),
),
ListTile(
title: Consumer<ListReceiver>(
builder: (_, a, child) => Text(a.secondList.toString()),
),
subtitle: Text(
context.select((ListReceiver l) => l.secondList).toString(),
),
),
SizedBox(
height: 300,
child: ListView.builder(
itemCount:
context.select((ListReceiver d) => d.secondList.length),
itemBuilder: (context, index) {
return Builder(
builder: (context) => ListTile(
title: Text(context.select((ListReceiver d) =>
d.secondList[index].toString())),
subtitle: Text('hi'),
));
},
),
),
],
),
),
);
}
}
class ListProvider extends ChangeNotifier {
List firstList = [];
var random = Random();
void addToList() {
firstList.add(random.nextInt(100));
notifyListeners();
}
}
class ListReceiver extends ChangeNotifier {
List secondList;
void displayList(List firstList) {
secondList = firstList;
notifyListeners();
print(secondList);
}
}
解决方案
我无法解释你的观察者行为:(
对于它的价值,更换:
ListTile(
title: Consumer<ListReceiver>(
builder: (_, a, child) => Text(a.secondList.toString()),
),
subtitle: Text(
context.select((ListReceiver l) => l.secondList).toString(),
),
),
和:
ListTile(
title: Text(context.watch<ListReceiver>().secondList.toString()),
subtitle: Text(
context.select((ListReceiver l) => l.secondList).toString(),
),
),
确实有效。
推荐阅读
- ruby - PG::ConnectionBad:无法将主机名“postgres”转换为地址:没有与主机名关联的地址
- c# - 如何单击子窗体上的十字按钮(取消按钮)并转到主窗体?
- c - 使用 Makefile 编译任何单个 C 代码
- c - C 新手尝试进行循环。Realloc():无效的下一个大小问题
- ios - Swift-调整约束以允许键盘
- flutter - formdata在颤动中转换为字符串
- python - 如何遍历文件的每一行并打印出任何包含两个相邻元音的单词?
- html - 有没有办法让这个 H1 在 div 的底部居中?
- python - 使用 Python 删除 Gmail 中的特定电子邮件
- python - 如何在类方法中就地更改列表元素