首页 > 解决方案 > 在 Flutters 列表视图构建器中切换单个项目的活动

问题描述

如何通过切换单个项目而不是整个列表来更改颜色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状态管理。

标签: fluttermobileflutter-layout

解决方案


感谢@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();
          },
        ),
      ),
    );
  }
}

推荐阅读