Why my list is not rebuild after rearanging items
1,229
Following is the working code. You were consuming the default values and were not consuming the change. Please refer the code below.
Edited
You should use ChangeNotifierProvider.value
for this use-case instead of ChangeNotifierProvider
. Difference
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter/foundation.dart';
import 'dart:math';
class InnerProvider extends ChangeNotifier {
int pid;
InnerProvider(this.pid);
get id => pid;
set id(int i) {
pid = i;
notifyListeners();
}
}
class OuterProvider extends ChangeNotifier {
List _data = [
InnerProvider(1),
InnerProvider(3),
InnerProvider(4),
InnerProvider(5),
];
get data => _data;
addToData(var item) {
data.add(item);
notifyListeners();
}
reShuffle() {
data.shuffle();
notifyListeners();
}
changeId(var i) {
var dtIndex = _data.indexOf(i);
_data[dtIndex].id = Random().nextInt(99);
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<OuterProvider>(
create: (_) => OuterProvider(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Why this does not work?'),
));
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List outerData;
void reShuffleData() {
Provider.of<OuterProvider>(context).reShuffle();
}
@override
Widget build(BuildContext context) {
outerData = Provider.of<OuterProvider>(context, listen: true).data;
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: ListView.builder(
itemCount: outerData.length,
itemBuilder: (context, int i) {
return ChangeNotifierProvider<InnerProvider>.value(
value: outerData[i],
child: InnerChild(),
);
})),
floatingActionButton: FloatingActionButton(
onPressed: reShuffleData,
tooltip: 'Shuffle',
child: Icon(Icons.add),
),
);
}
}
class InnerChild extends StatelessWidget {
Widget build(BuildContext context) {
var prov = Provider.of<InnerProvider>(context);
return Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
GestureDetector(
onTap: () {
Provider.of<OuterProvider>(context).changeId(prov);
},
child: Text(
Provider.of<InnerProvider>(context).id.toString(),
style: TextStyle(fontSize: 40),
)),
]);
}
}
Author by
Kozubi
Updated on December 16, 2022Comments
-
Kozubi over 1 year
This is toy app using Flutter and Provider package. My goals are simple: -
OuterProvider
have data which is used to build a list (ListView.builder
) -Outer provider
haveShuffle
button which shuffle inner list - Inner Widgets (Rows
) usesInnerProvider
to proceed with changing data randomlyWhen i click on
InnerWidget
- provider updates data correctly But when I shuffle data, even if data is shuffled. Build method is run but my widgets list is not affected….Here is sample code
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter/foundation.dart'; import 'dart:math'; class InnerProvider extends ChangeNotifier { int pid; InnerProvider(this.pid); get id => pid; set id(int i) { pid = i; notifyListeners(); } } class OuterProvider extends ChangeNotifier { List _data = [ InnerProvider(1), InnerProvider(3), InnerProvider(4), InnerProvider(5), ]; get data => _data; addToData(var item) { data.add(item); notifyListeners(); } reShuffle() { data.shuffle(); notifyListeners(); } changeId(var i) { var dtIndex = _data.indexOf(i); _data[dtIndex].id = Random().nextInt(99); } } void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return ChangeNotifierProvider<OuterProvider>( create: (_) => OuterProvider(), child: MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Why this does not work?'), )); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { List outerData; void reShuffleData() { Provider.of<OuterProvider>(context).reShuffle(); } @override Widget build(BuildContext context) { outerData = Provider.of<OuterProvider>(context, listen: true).data; return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: ListView.builder( itemCount: outerData.length, itemBuilder: (context, int i) { return ChangeNotifierProvider<InnerProvider>( create: (_) => outerData[i], child: InnerChild()); })), floatingActionButton: FloatingActionButton( onPressed: reShuffleData, tooltip: 'Shuffle', child: Icon(Icons.add), ), ); } } class InnerChild extends StatelessWidget { Widget build(BuildContext context) { var prov = Provider.of<InnerProvider>(context); return Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ GestureDetector( onTap: () { Provider.of<OuterProvider>(context).changeId(prov); }, child: Text( Provider.of<InnerProvider>(context).id.toString(), style: TextStyle(fontSize: 40), )), ]); } }