Reputation: 101
import 'package:flutter/material.dart';
import '../../Data/Globalvariable.dart' as global;
class MenuBar extends StatefulWidget {
final key = UniqueKey();
// final pin;
// MenuBar({this.pin='112'});
@override
_MenuBarState createState() {
return _MenuBarState();
}
}
class _MenuBarState extends State<MenuBar> {
ValueNotifier<List<String>> st = ValueNotifier(global.pincode);
Widget total() {
return ListView.builder(
itemCount: global.pincode.length,
itemBuilder: (context, index) {
final item = global.pincode[index];
return Dismissible(
key: UniqueKey(),
onDismissed: (direction) {
setState(() {
global.pincode.removeAt(index);
});
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('$item Removed')));
},
background: Container(color: Colors.red),
child: ListTile(
title: Text(item),
),
);
},
);
}
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
builder: (context, n, menu) {
print(global.pincode);
return total();
},
child: total(),
valueListenable: st,
);
}
}
this is my main file i have a global file and all of my working variables are there
Globalvariable.dart
library project.globals;
List<String> pincode = ['Select Pin','110084','110088'];
now as i am adding data into pincode valuenotifier should listen to it and update the widget automatically but it is not doing so i verified that using debug console it gets updated when i call setstate which is ok but i want to update widget as i add data to my list
this is to demonstrate what i said above that wigdet is updating on removal but not for addition
Upvotes: 4
Views: 14709
Reputation: 81
To make life easier, you can write a class that extends ValueNotifier<List> and define methods add and remove, as in the example below. and then just use _yourNotifier.add(newValue);
So u don't need to repeat List.from(st.value)..removeAt(index) and so on.
class ValueNotifierList<T> extends ValueNotifier<List<T>> {
ValueNotifierList(List<T> value) : super(value);
void add(T valueToAdd) {
value = [...value, valueToAdd];
}
void remove(T valueToRemove) {
value = value.where((value) => value != valueToRemove).toList();
}
}
Upvotes: 5
Reputation: 101
You don't need to use SetState if you already use ValueNotifier.
To update state, use: st.value = new value.
Because you already wrap your child widget with ValueListenableBuilder, the state will automatically change if value of st changes.
ValueNotifier uses equality to detect change. For List, the dart compiler won't notice any change if you only add/remove value of the list.
To overcome the problem, you need to create a new list so that the dart compiler detects the change.
You can update your code like this:
return Dismissible(
key: UniqueKey(),
onDismissed: (direction) {
st.value = List.from(st.value)..removeAt(index);
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('$item Removed')));
},
background: Container(color: Colors.red),
child: ListTile(
title: Text(item),
),
);
Upvotes: 10
Reputation: 454
If you're using ValueNotifier
with a list you should append to that list st
using st.value.add()
, modifying the global.pincode
list won't reflect unless you make that global list a ValueNotifier
.
So you'll either have st.value.add()
or in your global file ValueNotifier<List<String>> pincode = ValueNotifier(<String>[...]);
with a valueListenable: global.pincode
and modifications using global.pincode.value.xyz
Upvotes: 0