#flutter #provider #changenotifier
Вопрос:
У меня есть виджет, текст которого необходимо обновить на основе того, что введено в двух текстовых полях. Как правильно слушать два источника в этой ситуации (и в целом)?
Я только что написал два урока:
class MyTextField extends StatelessWidget {
const MyTextField({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
onChanged: (newData) => context.read<Data>().changeString(newData),
);
}
}
И MyTextField2
то же самое.
Виджет HomePage
:
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('build HomePage');
return Scaffold(
appBar: AppBar(
title: Container(child: Text(context.watch<Data>().getData),),
),
body: Center(
child: Column(
children: [
MyTextField(),
MyTextField2(),
Text(context.watch<Data>().getData),
],
),
)
);
}
}
Класс данных:
class Data with ChangeNotifier
{
String _data = 'some text';
String get getData => _data;
void changeString(String newString)
{
_data = newString;
notifyListeners();
}
}
Правильно ли я понимаю, что HomePage
виджет прослушивает два источника? Могут ли возникнуть конфликты, если оба TextField
изменения будут внесены одновременно?
Ответ №1:
Вы можете обернуть MaterialApp
свой основной файл.dart с помощью MultiProvider(providers: [//your providers])
Ответ №2:
Я протестировал ваш код, и он работал нормально. это основной файл:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'Data.dart';
import 'MyTextField.dart';
import 'MyTextField2.dart';
void main() {
runApp(
ChangeNotifierProvider<Data>(
create: (_) => Data(),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
return Scaffold(
appBar: AppBar(
title: Container(child: Text(context.watch<Data>().getData),),
),
body: Center(
child: Column(
children: [
MyTextField(),
MyTextField2(),
Text(context.watch<Data>().getData),
],
),
)
);
}
}
это и есть результат:
если вы хотите объединить два текстовых поля, вы можете изменить свой класс данных на:
import 'package:flutter/material.dart';
class Data with ChangeNotifier{
String _data1 = "";
String _data2 = "";
String get getData => _data1 _data2;
void changeString1(String newString){
_data1 =newString;
notifyListeners();
}
void changeString2(String newString){
_data2 =newString;
notifyListeners();
}
}
это и есть результат: