Reputation: 8026
In the following, my Sort
mixin class created a list of ItemStatefulWidget
widgets,
When a user clicks on a ItemStatefulWidget
widget, it calls setState()
to update the values stored in globalSortConfig, which is used by other sibling widgets.
However, setState
didn't trigger rebuild in other sibling widgets.
Sort Mixin Source Code:
import 'package:flutter/material.dart';
dynamic globalSortConfig = null;
//
// Sort Mixin
//
mixin Sort<T extends StatefulWidget> on State<T> {
List<Widget> sortWidgets;
dynamic mixinSorts;
@override
void initState() {
super.initState();
}
void showSortModal(context, Function callback) {
// set global sort config
if(globalSortConfig == null) {
globalSortConfig = mixinSorts;
}
// show modal
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
// build sort widgets
if (sortWidgets == null) {
sortWidgets = [];
for (var i = 0; i < mixinSorts.length; i++) {
sortWidgets.add(ItemStatefulWidget(i: i, callback: callback));
}
}
// return
return Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: sortWidgets),
),
);
},
);
}
dynamic getSortCriteria() {
dynamic criteria = {};
if (globalSortConfig != null) {
for (var i = 0; i < globalSortConfig.length; i++) {
if (globalSortConfig[i]['select'] == true) {
criteria['sort'] = globalSortConfig[i]['sort'];
criteria['order'] = globalSortConfig[i]['order'];
}
}
}
return criteria;
}
}
ItemStatefulWidget Source code
class ItemStatefulWidget extends StatefulWidget {
final int i;
final Function callback;
ItemStatefulWidget({Key key, this.i, this.callback}) : super(key: key);
@override
_ItemStatefulWidgetState createState() => _ItemStatefulWidgetState();
}
class _ItemStatefulWidgetState extends State<ItemStatefulWidget> {
@override
Widget build(BuildContext context) {
// var
int i = this.widget.i;
List<Widget> lineWidgets = [];
// checked icon
if (globalSortConfig[i]['select'] == true) {
Widget iconWidget = Icon(Icons.check);
lineWidgets.add(iconWidget);
}
// label
String label = globalSortConfig[i]['label'];
lineWidgets.add(GestureDetector(
child: Text(label,
style: TextStyle(fontSize: 20),
),
onTap: () {
setState(() {
// update value
globalSortConfig[i]['select'] = !globalSortConfig[i]['select'];
for (var w = 0; w < globalSortConfig.length; w++) {
if (w != i) {
globalSortConfig[w]['select'] = false;
}
}
// pop and callback
Future.delayed(const Duration(microseconds: 900), () {
Navigator.pop(context);
this.widget.callback();
});
});
},
));
// alignment
Widget row = Row(
mainAxisAlignment: MainAxisAlignment.center,
children: lineWidgets,
);
return row;
}
}
Upvotes: 1
Views: 279
Reputation: 680
It's not clear from you code what exactly the callback
function is or does, but it is only ever called on this.widget
, not on others. If you want the tap of one widget to trigger changes in the others, then I think a much cleaner way to implement this is to make your globalSortConfig
a (singleton?) object of a class that extends ChangeNotifierProvider
from the Provider
package. To change your config in the onTap
of the ItemStatefulWidget
you can then call a method on that object that also calls notifyListeners()
, and in the build
method of the ItemStatefulWidget
you listen to those changes using context.watch
, which will ensure that each ItemStatefulWidget
is rebuilt whenever the globalSortConfig
object changes.
Upvotes: 1