Единый выбор для ListView Flutter - PullRequest
1 голос
/ 21 июня 2020

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

ожидаемый результат

class BoxSelection{
  bool isSelected;
  String title;
  String options;
  BoxSelection({this.title, this.isSelected, this.options});
}


class _AddProjectState extends State<AddProject> {
  List<BoxSelection> projectType = new List();
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    projectType
        .add(BoxSelection(title: "Building", isSelected: false, options: "A"));
    projectType
        .add(BoxSelection(title: "Gym House", isSelected: false, options: "B"));
    projectType
        .add(BoxSelection(title: "School", isSelected: false, options: "C"));
  }

  child: ListView.builder(
                      itemCount: projectType.length,
                      itemBuilder: (BuildContext context, int index) {
                        return GestureDetector(
                          onTap: () {
                            setState(() {
       //here am trying to implement single selection for the options in the list but it don't work well
                              for(int i = 0; i < projectType.length; i++) {
                                if (i == index) {
                                  setState(() {
                                    projectType[index].isSelected = true;
                                  });
                                } else {
                                  setState(() {
                                    projectType[index].isSelected = false;
                                  });
                                }
                              }
                            });
                          },
                          child: BoxSelectionButton(
                            isSelected: projectType[index].isSelected,
                            option: projectType[index].options,
                            title: projectType[index].title,
                          ),
                        );
                      },
                    ),

1 Ответ

1 голос
/ 21 июня 2020

Ваша проблема в том, что вы используете index для доступа к элементам projectType, но вы должны использовать i

if (i == index) {
    setState(() {
    projectType[i].isSelected = true;
    });
} else {
    setState(() {
    projectType[i].isSelected = false;
    });
}  

В любом случае я думаю, что ваш код можно улучшить, поскольку он не настолько эффективно, насколько это возможно. Вы перебираете весь список и вызываете setState дважды на каждой итерации, повторно создавая дерево виджетов много раз без необходимости, когда это можно сделать за один снимок.

  1. Сохраните текущий выбор в переменной уровня класса

    BoxSelection _selectedBox
    
  2. Упростите свой код, чтобы он действовал непосредственно над текущим выбором, выполняя итерацию по всему списку

     onTap: () =>
       setState(() {
         if (_selectedBox != null) {
             _selectedBox.isSelected = false;
         }
         projectType[index].isSelected = !projectType[index].isSelected;
         _selectedBox = projectType[index];
       });   
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...