Flutter: скрыть / показать виджет по клавише из другого виджета

#flutter #dart #flutter-layout

#трепетание #дротик #трепетание-макет

Вопрос:

Я создаю анкету, в которой пользователь должен давать ответы на каждый вопрос.

Мой экран содержит пять вопросов, и у меня есть вопрос, который

Q2 Пожалуйста, выберите модель вашего автомобиля

  1. BMW (радио)
  2. AUDI (радио)
  3. Другое (радио)

Если пользователь нажимает на 3-й вариант, он должен показать другой вопрос

Q2: 1 Пожалуйста, введите марку вашего автомобиля

Этот вопрос изначально скрыт. Он отображается только тогда, когда пользователь нажимает на 3-ю опцию выше {Текстовое поле}.

Как динамически отображать / скрывать виджеты по ключу?

мой код для виджета:

  case ("RADIO"): // if answer type is equal to radio (majority of answers are radio)
        var index = listAnswers
            .indexWhere((pair) => pair['key'] == objQuestion.questionId);
        for (Answer ans in objQuestion.answers) {
          // fetching answer index
          var ansIndex = listAnswers[index]['answer']
              .indexWhere((pair) => pair['key'] == ans.answerId);
          answerWidget.add(
              //   StatefulBuilder(
              //   builder: (BuildContext context, StateSetter setState) {
              // return
              Container(
                  child: Padding(
            padding: EdgeInsets.all(10.0),
            child: RadioListTile(
              // key: _key,
              title: Text(ans.answerText),
              value: listAnswers[index]['answer'][ansIndex]['key'],
              groupValue: listAnswers[index]['selectedValue'],
              onChanged: (val) {
                setState(() {
                  listAnswers[index]['answer'].asMap().forEach(
                      (index, keyPair) => keyPair['value'] =
                          false); // making all other answer option selected value to false
                  listAnswers[index]['answer'][ansIndex]['value'] =
                      true; // making current answer option selected value to true
                  listAnswers[index]['selectedValue'] =
                      val; // setting current selected value to selected answer answerId which is key value

                  // if (val == 3)
                  //    widget.show() where key == qid2-1;
                  // else
                  // //    widget.hide() where key == qid2-1;
                });
              },
              secondary: const Icon(Icons.check),
              activeColor: Color.fromRGBO(223, 0, 61, 1),
            ),
          )));
          // }));
        }
        return answerWidget;
        break;
  

мой код для виджета, в котором я задаю вопросы.

 ListView generateForm() {
    return ListView.builder(
      itemCount: listQuestions.length,
      itemBuilder: (context, index) => Card(
        color: Color.fromRGBO(232, 232, 232, 1),
        elevation: 0,
        child: Padding(
          key: Key(listQuestions[index].questionNo.toString()),
          padding: const EdgeInsets.all(18.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Text(
                listQuestions[index].questionNo.toString()  
                    '. '  
                    listQuestions[index].questionText.toString(),
                style: TextStyle(
                  fontSize: 18.0,
                  fontWeight: FontWeight.normal,
                ),
              ),
              if (listQuestions[index].helpboxes?.isNotEmpty == true)
                FittedBox(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      // have to go inside expansion tile like we are doing for answers
                      FilterChip(
                        backgroundColor: Colors.grey[100],
                        label: Text(
                          listQuestions[index]
                              .helpboxes[0]
                              .helpboxText
                              .substring(1, 60),
                        ),
                        onSelected: (b) {},
                      )
                    ],
                  ),
                ),
              Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: getAnswerWidget(listQuestions[index]),
              ),
            ],
          ),
        ),
        //children: getAnswerWidget(form[index]),
      ),
    );
  }
  

Ответ №1:

Для этого вы можете использовать класс видимости Flutters.

 bool isVisible;

...

Visibility(
  visible: isVisible,
  child: TextView(
  ...
  ),
),
  

Затем вы можете изменить метод 3-го переключателя onChanged , чтобы установить для isVisible значение true (вам, вероятно, потребуется вызвать notifylisteners метод, поскольку объект изменится)
Дополнительная информация о видимости в flutter: https://api.flutter.dev/flutter/widgets/Visibility-class.html

Комментарии:

1. виджет видимости не будет работать, чтобы заставить его работать, я должен воссоздать виджеты.

2. Возможно, я что-то упускаю, но разве вы не можете перестроить страницу, как только пользователь нажмет на эту 3-ю кнопку, которая затем отобразит следующий вопрос (поскольку видимость изменилась бы)?

3. Я могу, это было первое решение, но проблема в том, что мы не можем перестроить весь экран, потому что это не будет выглядеть красиво для пользователя, им придется снова прокрутить вниз до конкретного вопроса, а также страница будет иметь эффект восстановления (типа мигания).