Flutter: средство подбора данных не изменяет список элементов пользовательского интерфейса после выбора

#flutter #dart

#флаттер #дротик

Вопрос:

Я пытаюсь изменить текстовый виджет внутри ListTile ListView после нажатия и выбора нового значения с помощью DataPicker.

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

После нажатия на ListTile я выберу новое значение для элемента Subtitle в ListTile (фактическое значение — «Выбрать …»)

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

После нажатия кнопки OK значение не изменяет элемент субтитров.

Средство выбора данных возвращает правильное значение, а затем я обновляю соответствующую переменную, связанную с текстовым виджетом:

Журнал консоли VSCode

 I/flutter ( 8578): Method onTap triggered
I/flutter ( 8578): Method onChange from showMaterialScrollPicker triggered
I/flutter ( 8578): New value:Option 2
  

Код:

 class _BodyState extends State<Body> {
  List<CaracteristicaListItem> caracteristicasList = <CaracteristicaListItem>[];

  @override
  Widget build(BuildContext context) {
    caracteristicasList = <CaracteristicaListItem>[
      CaracteristicaListItemScroll(
        "Test",
        Icon(
          Icons.bubble_chart,
          color: Colors.white70,
          size: 36.0,
        ),
        this,
        <String>["Option 1", "Option 2"],
      ),
    ];


/* 
 *   Some code
 */ 

              child: ListView.separated(
                separatorBuilder: (context, index) => Divider(
                  color: Colors.white70,
                ),
                itemBuilder: (BuildContext context, int index) {
                  var caracteristica = caracteristicasList[index];
                  return Material(
                    color: Colors.white24,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.only(
                        topRight: Radius.circular(100),
                        bottomRight: Radius.circular(100),
                      ),
                      side: BorderSide(style: BorderStyle.none),
                    ),
                    child: ListTile(
                      leading: caracteristica.icon,
                      title: caracteristica.textTitle,
                      subtitle: caracteristica.textSubtitle,
                      onTap: () => caracteristica.onTap(),
                    ),
                  );
                },
                itemCount: caracteristicasList.length,
              ),
  

Код onTap

 // Generic class
abstract class CaracteristicaListItem {
  final String title;
  final Icon icon;
  final _BodyState state;
  Text textTitle;
  Text textSubtitle;
  String subtitle = "Select...";
  bool isValueChanged = false;

  CaracteristicaListItem(this.title, this.icon, this.state) {}

  void onTap();
}

// Scroll DataPicker
class CaracteristicaListItemScroll extends CaracteristicaListItem {
  final List<String> scrollData;

  CaracteristicaListItemScroll(
      String title, Icon icon, _BodyState state, this.scrollData)
      : super(title, icon, state) {
    // Generate a Text() elements
    textTitle = _buildTitle();
    textSubtitle = _buildSubtitle();
  }

  // Tap Handler
  @override
  void onTap() {
    print("Method onTap triggered");

    // Call Addon flutter_material_pickers: ^1.7.3
    showMaterialScrollPicker(
      showDivider: true,
      context: state.context,
      title: "Select",
      items: scrollData,
      selectedItem: isValueChanged ? super.subtitle : scrollData[0],
      onChanged: (value) {
        print("Method onChange from showMaterialScrollPicker triggered");
        print("New value: "   value);
        super.subtitle = value;
        isValueChanged = true;
      },
    );
  }

  Text _buildTitle() {
    // Generate a Text() with variable escape
    // to update after selection using DataPicker
    return Text(
      "$title",
      style: TextStyle(
        color: Colors.white70,
        fontWeight: FontWeight.bold,
        fontSize: 24.0,
      ),
    );
  }

  Text _buildSubtitle() {
    // Generate a Text() with variable escape
    // to update after selection using DataPicker
    return Text(
      "$subtitle",
      style: TextStyle(
        color: Colors.white70,
        fontSize: 18.0,
      ),
    );
  }
}
  

Ответ №1:

Вы можете попробовать поместить setState((){}) внутри вашего onTap, чтобы фактически перестроить пользовательский интерфейс. Вот так :

 SetState((){ 
        super.subtitle = value;
        isValueChanged = true; });
  

Что делает setState, так это уведомляет фреймворк о том, что внутреннее состояние этого объекта изменилось

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

1. Спасибо, это решило мою проблему. Но сначала мне также нужно было преобразовать мой ListTile в StatefulWidget.