Flutter - как реализовать выпадающий список с помощью BloC?

Я хотел бы добавить в мое приложение раскрывающийся список, содержащий «имена», вместо TextField, как в приведенном ниже коде. Как я могу сделать это с помощью BloC?

class PersonPage extends StatefulWidget {

  PersonPage(this.person);
  final Person person;

  @override
  _PersonPageState createState() => _PersonPageState();
}

class Names{
  const Item(this.name);
  final String name;
}

class _PersonPageState extends State<PersonPage> {
  Item selectedUser;
  List<Item> names = <Names>[
   const Item('Thomas'),
   const Item('John'),
   const Item('Mary'),
   const Item('Lukas'),
  ];
 TextEditingController _nameController;

 final _bloc = PersonBloc();

 @override
 void initState() {

  _bloc.setPerson(widget.person);
  _nameController = TextEditingController(text: widget.person.name);

  super.initState();
 }
@override
void dispose() {
 _nameController.dispose();
 super.dispose();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text("MyApp"),
    ),
    body: Container(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ListView(
          children: <Widget>[             
            Container(
              child: TextField(
                decoration: InputDecoration(labelText: "Name"),
                controller: _nameController,
                onChanged: _bloc.setName,
              ),
            ),
            Container(
              height: 20,
            ),              
            RaisedButton(
              child: Text("Save"),
              onPressed: () {
                if (_bloc.insertOrUpdate()) {
                  Navigator.pop(context);
                }
              },
            )
          ],
        ),
      ),
    ),
  );
}

Спасибо.


person Marcio    schedule 08.01.2020    source источник


Ответы (1)


Я дам вам пример, и вы попытаетесь применить в своем коде

class _PersonPageState extends State<PersonPage> {
  final _bloc = PersonBloc();

  @override
  void initState() {

    _bloc.setPerson(widget.person);
    _nameController = TextEditingController(text: widget.person.name);

   super.initState();
  }

  @override
  void dispose() {
    _nameController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text("MyApp"),
    ),
    body: Container(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ListView(
          children: <Widget>[             
            StreamBuilder(
              stream: bloc.outName,
              builder: (context, snapshot) {
                if (!snapshot.hasData)
                  return Container();

                return DropdownButton(
                  hint: Text("Names"),
                  value: snapshot.data,
                  items: bloc.names.map((item) {
                    return DropdownMenuItem(
                      value: item,
                      child: Row(children: <Widget>[Text(item),]),
                    );
                  }).toList(),
                  onChanged: bloc.inName,
                );
              },
            ),
            Container(
              height: 20,
            ),              
            RaisedButton(
              child: Text("Save"),
              onPressed: () {
                if (_bloc.insertOrUpdate()) {
                  Navigator.pop(context);
                }
              },
            )
          ],
        ),
      ),
    ),
  );
}

Измените свой список имен на свой BLoC и создайте имя BehaviorSubject

PersonBloc{

  List<String> names = ['Thomas', 'John', 'Mary', 'Lukas'];

  final _name = BehaviorSubject<String>.seeded("");
  Stream<String> get outName  => _name.stream;
  Function(String) get inName => _name.sink.add;
  //TODO - Don't forget to dispose this _name

}

Теперь ваш _name имеет выбранное имя, и чтобы получить имя, вам просто нужно сделать

Person.name = _name.stream.value;

Этот пример можно улучшить, это всего лишь черновик

person Matheus Ribeiro    schedule 09.01.2020
comment
Привет @Mateus! Спасибо за отзыв. Я проверял ваше предложение, но, к сожалению, оно не работает. На экране ничего не показывает, ошибок нет, но на дисплее ничего не отображается. Есть предложения по этому поводу? - person Marcio; 09.01.2020
comment
@Michael Я изменил свой пример, пожалуйста, взгляните еще раз и посмотрите, работает ли он. Если по-прежнему не работает, попробуйте создать экземпляр следующим образом seeded("Thomas") - person Matheus Ribeiro; 09.01.2020
comment
Сейчас он работает, но для этого пришлось его удалить: if (!snapshot.hasData) return Container(); - person Marcio; 09.01.2020
comment
Большое спасибо ... Это именно то, что я искал. Желаю Вам всего наилучшего. :) - person md. ariful ahsan; 16.05.2021