Состояние установки флаттера не обновляет значение переменной в функции нижнего листа

У меня есть кнопка, при нажатии на которую я вызываю следующую функцию, которая создает нижний лист ниже. Что происходит, так это то, что она создает список карточек на основе значения массива списка. Затем на одной из карточек я хочу обновить ее значение на основе жеста onTap. Я заметил, что он обнаруживает жест, но не обновляет его значение. Прежде всего, у меня есть глобальная переменная, определенная как

String _localPNumberSelected="";

В onTap я вызываю setState

setState(() {                                                   
 _localPNumberSelected=vList[index]["pNumber"].toString();
});

но это не обновляет

children: [
  new Text('$_localPNumberSelected'),                                                
],

Вот полные коды.

void _callQuickListModalBottomSheet(context){
    Future<void> future = showModalBottomSheet<void>(
      context: context,
      builder: (BuildContext bc){
          return Container(
            height: 280,
            margin: new EdgeInsets.fromLTRB(200, 0, 10, 0),
            child : new Container(
              decoration: new BoxDecoration(
                 color: Color.fromRGBO(36, 46, 66, 1),
                 borderRadius: new BorderRadius.only(
                   topLeft: const Radius.circular(20),
                   topRight: const Radius.circular(20)
                 ),                 
              ),
              child: new Column(                    
                      children: <Widget>[
                        new Container(
                        margin: new EdgeInsets.fromLTRB(10, 10, 10, 0),
                        height:45,
                        child: new Column(
                        children: <Widget>[
                          new Card(
                                    color: Colors.white,
                                    child: Row (
                                    children: <Widget>[
                                              new Column(
                                                 mainAxisAlignment: MainAxisAlignment.center,
                                                 crossAxisAlignment: CrossAxisAlignment.center,
                                                 children: <Widget>[
                                                   Container(
                                                      decoration: new BoxDecoration(
                                                      color: Colors.green,
                                                      borderRadius: new BorderRadius.only(
                                                        topLeft: const Radius.circular(5),
                                                        bottomLeft: const Radius.circular(5)
                                                      ),
                                                      ),
                                                  child: Icon(Icons.check, size: 20.0),
                                                  height: 27,
                                                  width: 30,
                                                ),
                                              ],
                                              ),
                                              new Column(
                                                mainAxisAlignment: MainAxisAlignment.center,
                                                crossAxisAlignment: CrossAxisAlignment.center,
                                                mainAxisSize: MainAxisSize.max,
                                                children: [
                                                        new Text('$_localPNumberSelected'),

                                               ],
                                             ), 
                                      ],
                                    )
                          )
                        ]
                        )
                        ),
                        new Container(
                        height:190,                        
                        child:
                        new ListView.builder(
                          shrinkWrap: true,
                          itemCount: vehicleListdata.length,                          
                          itemBuilder: (BuildContext ctxt, int index) {
                            return Container(
                              margin: new EdgeInsets.fromLTRB(10, 0, 10, 0),
                              width: 30.0,
                              height: 35.0,                         
                                  child: Card(
                                    color: Colors.white,
                                    child: Row (
                                    children: <Widget>[
                                              new Column(
                                                 mainAxisAlignment: MainAxisAlignment.center,
                                                 crossAxisAlignment: CrossAxisAlignment.center,
                                                 children: <Widget>[
                                                 Container(
                                                      decoration: new BoxDecoration(
                                                      color: Colors.amber,
                                                      borderRadius: new BorderRadius.only(
                                                        topLeft: const Radius.circular(5),
                                                        bottomLeft: const Radius.circular(5)
                                                      ),

                                                    ),
                                                  height: 27,
                                                  width: 10,

                                                  ),
                                              ],
                                              ),
                                              new Column(
                                                mainAxisAlignment: MainAxisAlignment.center,
                                                crossAxisAlignment: CrossAxisAlignment.center,
                                                mainAxisSize: MainAxisSize.max,
                                                children: [
                                                     new GestureDetector(
                                                          onTap: () {
                                                            setState(() {
                                                              _localPNumberSelected=vList[index]["pNumber"].toString();
                                                            });
                                                          doSomething(vList[index]["pNumber"].toString());
                                                        }, 
                                                        child:new Text(vList[index]["pNumber"].toString()),    
                                                       ),

                                            ],
                                          ), 
                                      ],
                                    ),


                                  )
                            );

                          }
                        )
                        )
                      ],
                    ),
            )
          );
      }
    );
    future.then((void value) => _closeModal(value));
}

person newbie    schedule 27.02.2019    source источник
comment
Любой setState на нижнем листе не отражает, потому что он находится в новом контексте. Попробуйте сделать нижний лист виджетом с отслеживанием состояния и самостоятельно поддерживать его состояние. Если вы хотите передать значение с помощью Navigator.of(context).pop('value').   -  person Hemanth Raj    schedule 27.02.2019
comment
@HemanthRaj есть ли для меня какой-нибудь пример создания виджета с отслеживанием состояния, а затем он может взаимодействовать с моей функцией onTap   -  person newbie    schedule 27.02.2019


Ответы (3)


showModalBottomSheet не восстанавливается при использовании setState. Если вы хотите изменить значения внутри bottomSheet после того, как вы его создали, вам нужно будет реализовать свою собственную версию bottomSheet (просто создайте виджет с отслеживанием состояния, который ведет себя таким же образом)

person Serl    schedule 27.02.2019
comment
@seri любой пример того, как перейти к моему собственному нижнему листу, потому что, если вы заметили, мне также нужно вызвать функцию в функции при нажатии. - person newbie; 27.02.2019
comment
@newbie, github.com/flutter/flutter/issues/2115, взгляните на некоторые комментарии в этом выпуске. - person Serl; 27.02.2019
comment
почему showModalBottomSheet не перестраивается, когда мы используем setState? - person darshan; 07.08.2020

См. пример

 String update = '更新';

  ///选择省市
  void locationSheet() {
//    showModalBottomSheet(
//        context: context,
//        builder: (BuildContext context) {
//          return LocationPicker();
//        });

    showModalBottomSheet(
        context: context,
        builder: (BuildContext context) {
          return StatefulBuilder(builder: (context,state){
            return Center(
              child: FlatButton(
                  onPressed: () {
                    updated(state);
                  },
                  child: new Text('$update')),
            );
          });
        });
  }

  Future<Null> updated(StateSetter updateState) async {
    updateState(() {
      update = '更新后';
    });
  }
person SilenceCodder    schedule 02.11.2019
comment
Потрясающая реализация. - person alter123; 15.11.2019
comment
Работает как шарм! - person Heddie Franco; 09.06.2020
comment
Действительно хороший ответ. tx - person Mahdi Bagjani; 03.10.2020

Вы можете просто вернуть конструктор с отслеживанием состояния, который, в свою очередь, возвращает виджет, который вы пытаетесь вызвать.

showModalBottomSheet(
context: context,
builder: (context) {
  return StatefulBuilder(
      builder: (BuildContext context, StateSetter setState /*You can rename this!*/) {
    return Container(
      height: heightOfModalBottomSheet,
      child: RaisedButton(onPressed: () {
        setState(() {
          heightOfModalBottomSheet += 10;
        });
      }),
    );
  });

});

https://www.codegrepper.com/code-examples/whatever/how+to+change+state+of+Bottomsheet+in+flutter

Ссылка на оригинальный ответ - ШахбазАли (5 ноября 2020 г.).

person Johnpaul Muoneme    schedule 01.07.2021