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
have Shuffle
button which shuffle inner list
- Inner Widgets (Rows
) uses InnerProvider
to proceed with changing data randomly
When 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),
)),
]);
}
}