Как изменить свойство других элементов списка, когда один из них нажал во Флаттере - PullRequest
1 голос
/ 14 апреля 2020

Что я пытаюсь сделать

У меня есть класс Choice, который включает в себя список, как показано ниже.

class Choice {
  Choice({this.title, this.selected});

  final String title;
  final IconData icon;

  bool selected;
}

List<Choice> categoryChoices = <Choice>[
  Choice(title: 'Highlights', selected: true),
  Choice(title: 'Coming Up', selected: false),
  Choice(title: 'England', selected: false),
  Choice(title: 'Germany', selected: false),
  Choice(title: 'Italy', selected: false),
  Choice(title: 'Spain', selected: false),
  Choice(title: 'France', selected: false),
  Choice(title: 'Turkey', selected: false),
];

Также у меня есть класс ChoiceButton, который генерирует GestureDetectors на основе списка выбора выше.

class ChoiceButton extends StatefulWidget {
  ChoiceButton({this.choice, this.onPressed});

  final Choice choice;
  final Function onPressed;

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

class _ChoiceButtonState extends State<ChoiceButton> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      child: Container(
        alignment: Alignment.center,
        child: Text(
          widget.choice.title,
          style: kTextStyleButtonPrimary.copyWith(
              fontSize: 16.0, fontWeight: FontWeight.normal),
        ),
        decoration: BoxDecoration(
          color: widget.choice.selected ? Colors.blue : Colors.white,
          borderRadius: BorderRadius.circular(10.0),
          border: Border.all(
            color: Colors.blue,
          ),
        ),
        height: 40.0,
        width: 120.0,
      ),
      onTap: widget.onPressed,
    );
  }
}

В чем проблема

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

            Padding(
              padding: EdgeInsets.only(
                  left: 12.0, right: 12.0, top: 8.0, bottom: 2.0),
              child: SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: categoryChoices.map((Choice choice) {
                    print(choice);
                    return Padding(
                      padding: EdgeInsets.only(
                          left: 4.0, right: 4.0, top: 2.0, bottom: 2.0),
                      child: ChoiceButton(
                        choice: choice,
                        onPressed: () {
                          //var index = categoryChoices.indexOf(choice);
                          setState(() {
                            choice.selected = true;
                          });
                        },
                      ),
                    );
                  }).toList(),

1 Ответ

1 голос
/ 14 апреля 2020

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

class ChoiceButton extends StatefulWidget {
  ChoiceButton({this.choice, this.onPressed, this.selectedChoice});

  final String selectedChoice; // Add this field to keep track of current selected choice value
  final Choice choice;
  final Function onPressed;

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

class _ChoiceButtonState extends State<ChoiceButton> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      child: Container(
        alignment: Alignment.center,
        child: Text(
          widget.choice.title,
          style: TextStyle(
              fontSize: 16.0, fontWeight: FontWeight.normal),
        ),
        decoration: BoxDecoration(
          // The selection is made based on currently selected value
          color: widget.selectedChoice == widget.choice.title ? Colors.blue : Colors.white,
          borderRadius: BorderRadius.circular(10.0),
          border: Border.all(
            color: Colors.blue,
          ),
        ),
        height: 40.0,
        width: 120.0,
      ),
      onTap: widget.onPressed,
    );
  }
}

И в вашем файле (куда вы собираетесь использовать кнопку выбора) объявить переменную для отслеживания выбранного значения)

String selectedValue;

А теперь измените код инициализации ChoiceButton на:

ChoiceButton(
   choice: choice,
   selectedChoice: selectedValue,
   onPressed: () {
      setState(() {
         selectedValue = choice.title;
      });
   },
),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...