在 Flutter Listview 构建器中为单个项目切换 activity

Toggle activity for a single item in Flutters List View builder

如何通过切换单个项目而不是 Flutters List View builder 中的整个列表来更改颜色?当我点击卡片的按钮时,我只想更改该卡片的颜色,而不是整个列表。这是代码,目前正在切换列表中的所有项目:

bool _active = false;

  void _handleTap(index) {
    setState(() {
      _active = !_active;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: FutureBuilder<HTTPResponse<List<UserData>>>(
          future: _getUserList(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Consumer<UserDataModel>(
                builder: (context, userData, child) {
                  return ListView.builder(
                    itemCount: userData.userList.length,
                    itemBuilder: (context, index) {
                      UserData users =
                          userData.getUserbyIndex(index);
                      return Card(
                        child: Container(
                          decoration: BoxDecoration(
/// Here is where I toggle the colors but for the WHOLE list and not just a SINGLE item from the list
                            color: _active ? Colors.white : Colors.grey[400],
                          ),
                          padding: EdgeInsets.all(10.0),
                          child: PopupMenuButton<UserDropDownMenu>(
                                    onSelected: (action) {
                                      switch (action) {
                                        case UserDropDownMenu.activity:
                                          _handleTap(index);
                                          break;
                                      }
                                    },
                                    itemBuilder: (BuildContext context) =>
                                      const PopupMenuItem<UserDropDownMenu>(
                                        value: UserDropDownMenu.activity,
                                        child: Text('Active/Inactive'),
                                      ),
                                  ),
                          }
                      );
                    },
                  );
                },
              );
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }
            return Container();
          },
        ),
      ),
    );
  }
}

我也在使用 Provider 进行状态管理,如果情况有所改变的话。

感谢@pskink 的帮助,这是我的问题的答案:

/// This is BAD since you only return one boolean value and I needed multiple items from  the list to be toggled
bool _active = false;

  void _handleTap(index) {
    setState(() {
      _active = !_active;
    });
  }

//// This is GOOD (or at least the right approach) since I needed multiple choices
/// this stores the indices of active items like @pskink said, so you can toggle each item in the list
Set active = {};

void _handleTap(index) {
    setState(() {
      active.contains(index) ? active.remove(index) : active.add(index);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: FutureBuilder<HTTPResponse<List<UserData>>>(
          future: _getUserList(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Consumer<UserDataModel>(
                builder: (context, userData, child) {
                  return ListView.builder(
                    itemCount: userData.userList.length,
                    itemBuilder: (context, index) {
                      UserData users =
                          userData.getUserbyIndex(index);
                      return Card(
                        child: Container(
                          decoration: BoxDecoration(
/// This is where the widget checks which item in the list is selected and change color when you trigger the _handleTap() method
                            color: active.contains(index) ? Colors.white : Colors.grey[400],
                          ),
                          padding: EdgeInsets.all(10.0),
                          child: PopupMenuButton<UserDropDownMenu>(
                                    onSelected: (action) {
                                      switch (action) {
                                        case UserDropDownMenu.activity:
// where you call the method and the colors of the widget toggle
                                          _handleTap(index);
                                          break;
                                      }
                                    },
                                    itemBuilder: (BuildContext context) =>
                                      const PopupMenuItem<UserDropDownMenu>(
                                        value: UserDropDownMenu.activity,
                                        child: Text('Active/Inactive'),
                                      ),
                                  ),
                          }
                      );
                    },
                  );
                },
              );
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }
            return Container();
          },
        ),
      ),
    );
  }
}

我看到了这个 post 因为我还想在提供者的项目列表中只实现一张卡。这是我的解决方法

provider.dart

List<Category> _items = categoryDummyData;

//Method for toggling single card in a list provided
    void toggleSingleCardSelection(int index) {
    for (int indexBtn = 0; indexBtn < _items.length; indexBtn++) {
      if (indexBtn == index) {
        _items[indexBtn].isSelected = true;
        print('Item ${_items[indexBtn].title} is selected ');
      } else {
        _items[indexBtn].isSelected = false;
      }
    }
    notifyListeners();
  }

categories.dart

final categoryItems = Provider.of<Categories>(context);
return InkWell(
      onTap: () => categoryItems.toggleSingleCardSelection(index),
      child: Card(
        color:
            //set the background color of the button when it is selected/ not selected
            categoryItem.isSelected ? kcPrimaryColor : Colors.white,