When ListView.builder was removed, context.select
doesn't update the Ui. Wondering why that's the case.
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);
}
}
I cannot explain your observer behaviour :(
For what it is worth, replacing:
ListTile(
title: Consumer<ListReceiver>(
builder: (_, a, child) => Text(a.secondList.toString()),
),
subtitle: Text(
context.select((ListReceiver l) => l.secondList).toString(),
),
),
with:
ListTile(
title: Text(context.watch<ListReceiver>().secondList.toString()),
subtitle: Text(
context.select((ListReceiver l) => l.secondList).toString(),
),
),
does work.