#flutter #dart #flutter-provider
Вопрос:
Есть ли другой метод, который может заменить notifyListeners?
Я должен обновить поставщика, но другим способом.
Комментарии:
1. Это потому, что вы не хотите, чтобы все остальные слушатели слушали, а просто хотите, чтобы слушало определенное свойство?
2. да, это так….
Ответ №1:
Я могу предложить два способа сделать это. Например, в этом случае я изменяю текстовое поле с помощью поставщика:
1. Уведомитель о значении Поставщик
Класс поставщика TextProvider
class TextProvider extends ChangeNotifier {
final ValueNotifier<String> _textNotifier = ValueNotifier<String>('');
ValueNotifier<String> get text => _textNotifier;
void setText(String text) => _textNotifier.value = text;
}
В любом месте ниже контекста поставщика:
Column(
children: [
TextField(
onChanged: (value) {
Provider.of<TextProvider>(context, listen: false)
.setText(value);
},
),
SizedBox(
height: 20,
),
ValueListenableBuilder<String>(
valueListenable:
Provider.of<TextProvider>(context, listen: false).text,
builder: (context, value, _) => Text(
'$value',
style: Theme.of(context).textTheme.headline4,
),
),
],
2. Функция Обратного вызова Поставщик
Класс поставщика TextProvider
typedef TextCallback = void Function(String text);
class TextProvider extends ChangeNotifier {
final _textListener = ObserverList<TextCallback>();
void textListener(TextCallback callback) => _textListener.add(callback);
void _notifyTextChanged(String text) {
for (final listener in _textListener) {
listener.call(text);
}
//notifyListeners(); //Can call if you want to notify other listeners
}
void triggerTextChange(String text) => _notifyTextChanged(text);
}
В любом месте ниже контекста поставщика:
...
class _MyHomePageState extends State<MyHomePage> {
late final TextProvider provider;
String? text;
@override
void initState() {
super.initState();
provider = Provider.of<TextProvider>(context, listen: false);
provider.textListener((String s) {
setState(() {
text = s;
});
});
}
...
@override
Widget build(BuildContext context) {
...
child: Column(
children: [
TextField(
onChanged: (value) {
provider.triggerTextChange(value);
},
),
SizedBox(
height: 20,
),
Text(
'$text',
style: Theme.of(context).textTheme.headline4,
),
],
),
...
}