I am unable to figure out how I can listen to changes in a class that uses the ChangeNotifier class. More specifically, outside the widget build method. So far I've tried simply attaching listeners to the class like so:
final providerObj = SomeProvider();
void initState() {
providerObj.addListener(() {
print("Something happens");
});
}
But this does nothing. I don't know why. I got it working once, but afterwards it just died on me. Nothing gets triggered, when there is a change in the provider class' variable values.
Here's a snippet of the SomeProvider
class SomeProvider with ChangeNotifier {
int _tabIndex = 0;
List<Tab> _tabs = [];
Tab _searchTab = new Tab(id: 0, name: 'Search');
void searchItems(String searchWord) {
_searchTab.items.addAll(_items
.where((item) => product.item.contains(searchWord))
.toList());
setTabIndex(0);
}
void setTabIndex(int index) {
_tabIndex = index;
notifyListeners();
}
/// Get all products
List<Category> get tabs {
return [..._tabs];
}
int get tabIndex {
return _tabIndex;
}
What I'm trying to accomplish is simple: Control the selected tab, when the selected index is in the SomeProvider class. Every time a tab is pressed, the index value gets saved in the provider. When the value changes, it should trigger an animateTo() call for a TabController instance.
The reason for this is because I have a separate search widget, which needs to change the tab to a Search tab. I just have no idea how I can listen to changes in the provider class outside the build() method and change the TabController index there.
So, I have a basic TabBarView to which I give a TabController instance.
class _ProductsState extends State<Products> with TickerProviderStateMixin {
late TabController _tabController;
void initState() {
super.initState();
_tabController = TabController(
vsync: this,
length: 0,
initialIndex: 0,
);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
Future<void> _fetchTabs(context) async {
await Provider.of<SomeProvider>(context, listen: false)
.fetchTabs();
_tabController = TabController(
vsync: this,
length: Provider.of<SomeProvider>(context, listen: false)
.tabs
.length,
);
}
Widget build(BuildContext context) {
// There's a FutureBuilder here etc.
...
child: TabBarView(
controller: _tabController,
...
What I'm trying to do is something like:
void triggeredWhenStateChanges() {
_tabController.animateTo(Provider.of<SomeProvider>(context, listen: false).tabIndex);
}
Little bit off-topic: I've used React before (not React-Native) and with it you can use something called a hook which can perform side effects when a value change is detected. With the useEffect hook I can normally execute some actions when a value in the state changes. I don't know how I can do this with Flutter, if it can be done at all.