Как динамически изменить цвет фона поднятой кнопки в onPressed () - PullRequest
1 голос
/ 11 апреля 2019

У меня есть список поднятых кнопок, я хочу изменить цвет фона выбранной кнопки в ее onPressed ()

Я попытался изменить цвет в setState, но он ничего не делает.

Это функция, которая генерирует список кнопок

List<Widget> _makeZoneList(List<Zone> zones) {
    List<Widget>Buttons = new List();
    for (int i = 0; i < zones.length; i++) {
      Buttons.add(RaisedButton(
        color: zones[i].isSelected ? AppColors.primaryColor : AppColors.white,
        onPressed: () {
          setState(() {
            if (zones[i].isSelected){
              zones[i].isSelected = false;
            }
            else{
              zones[i].isSelected = true;
            }
            print(zones[i].isSelected.toString());
          });
        },
        child: Text(zones.elementAt(i).text)
      ));
    }
    return Buttons;
  }

Здесь я вызываю функцию

Widget _zoneBody() {
    return Padding(
        padding: EdgeInsets.all(32),
        child: StreamBuilder<List<Zone>>(
            stream: GetterBloc.zonesStream,
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return new Container();
              } else {
                if (snapshot.hasData) {
                     return Wrap(
                          spacing: 6.0, // gap between adjacent chips
                          children: _makeZoneList(snapshot.data));

                } else {
                  return new Container();
                }
              }
            }));
  }

Когда я нажимаю любую кнопку, ее значение isSelected изменяется, нофон не меняется соответственно

Ответы [ 3 ]

0 голосов
/ 11 апреля 2019

Что вы можете сделать, это создать свойство "color" (не требуется устанавливать какое-либо значение для него) в классе Zone. Затем установите для свойства color RaisedButton значение zone.color ??= AppColors.primaryColor.

А теперь внутри функции onPressed вы можете проверить, если !zone.isSelected, тогда установить zone.color = Colors.white.

Ниже приведена реализация для создания RaisedButton. Вы также можете проверить полную реализацию здесь

List<Widget> _createButton(BuildContext context, List<Zone> zones) {
    return zones.map((Zone zone) {
      return RaisedButton(
        onPressed: () {
          setState(() {
            if (!zone.isSelected) {
              zone.color = AppColors.white;
            }
          });
        },
        color: zone.color ??= Theme.of(context).primaryColor,
        child: Text(zone.text),
      );
    }).toList();
  }
0 голосов
/ 11 апреля 2019

Было трудно реализовать ваш код из-за неопределенных классов и переменных, однако я создал небольшой пример, который поможет вам в том, что вы ищете.

List<bool> _list = [true, false, true, false];

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text("Title")),
    body: ListView(children: _buildButtons()),
  );
}

List<Widget> _buildButtons() {
  List<Widget> listButtons = List.generate(_list.length, (i) {
    return RaisedButton(
      color: _list[i] ? Colors.green : Colors.red,
      onPressed: () {
        setState(() {
          _list[i] = !_list[i];
        });
      },
      child: Text("Button #${i}"),
    );
  });
  return listButtons;
}

Выход:

enter image description here

0 голосов
/ 11 апреля 2019

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

Однако есть и причина, по которой вы не работаете. Вы не включили достаточно кода, чтобы я мог сказать, но я считаю, что причина того, что вы делаете, не работает, в том, что у вас есть список данных, которые вы изменяете при нажатии кнопки (т.е. zones[i].isSelected = false;). Вы делаете это в setState, но способ, которым этот флаттер проверяет, нуждается ли что-то в восстановлении, - это сравнение на равенство между членами государства (то есть он будет проверять, есть ли зоны == зоны).

Поскольку 'zone' - это просто список и фактически тот же список для старого и нового состояния, flutter будет предполагать, что ничего не изменилось, и не будет беспокоить восстановление.

Есть два простых способа обойти это. Можно было бы сделать копию списка каждый раз, когда он изменяется, и установить для него элемент zones, чтобы при флаттере выполнялось сравнение old.zones != new.zones. Другой способ - сохранить отдельный объект, который вы изменяете при каждом изменении списка (я обычно использую целое число с именем changeCounter, которое я увеличиваю при каждом изменении списка), так как вы можете «обмануть» трепетание при перестройке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...