Как прослушивать несколько источников в flutter с помощью определителя изменений?

#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();
 }
}
 

это и есть результат:

введите описание изображения здесь