首页 > 解决方案 > 如何在 ListView.builder 中一次选择一项?

问题描述

我有一个名为 Emotion 的有状态小部件,它在其下方显示一个图标和文本,图标变为绿色,并且在点击图标后显示文本。我的屏幕容器中还有一个显示“情绪”的列表视图,如下所示:

Expanded(
                child: ListView.builder(
                    itemExtent: 100,
                    itemCount: moodIcons.length,
                    shrinkWrap: true,
                    scrollDirection: Axis.horizontal,
                    itemBuilder: (context, index) {
                      return Emotions(
                        icon: moodIcons[index],
                        textIcon: textIcons[index],
                      );
                    }),
              )
class Emotions extends StatefulWidget {
  final IconData icon;
  final String textIcon;

  const Emotions({Key key, this.icon, this.textIcon}) : super(key: key);
  @override
  _EmotionsState createState() => _EmotionsState();
}

class _EmotionsState extends State<Emotions> {
  bool _isPressed = false;
  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      duration: Duration(milliseconds: 350),
      curve: Curves.easeIn,
      child: Column(
        children: [
          GestureDetector(
            onTap: () {
              setState(() {
                _isPressed = !_isPressed;
              });
            },
            child: Icon(
              widget.icon,
              size: 40,
              color: _isPressed ? Colors.green : Colors.black,
            ),
          ),
          Text(
            widget.textIcon,
            style: TextStyle(
                color: _isPressed
                    ? Colors.black.withOpacity(0.7)
                    : Colors.black.withOpacity(0.0)),
          ),
        ],
      ),
    );
  }
}

我使用了以下 2 个列表:

List<IconData> moodIcons = <IconData>[
    Icons.mood_bad,
    Icons.sentiment_very_dissatisfied,
    Icons.sentiment_dissatisfied,
    Icons.sentiment_satisfied,
    Icons.sentiment_very_satisfied
  ];
  List<String> textIcons = <String>[
    "bad mood",
    "very sad",
    "sad",
    "happy",
    "very happy"
  ];

如何使此 Emotion 小部件列表一次仅选择一项?

标签: flutterdart

解决方案


如果您正在寻找嵌入在颤振框架中的答案;我不知道与 ListView 或其任何构造函数相关的任何内容。ListView Widget 用于显示作为参数传递的子项,而无需更改这些元素内的状态。

我对您的建议是具有与对象相同的元素列表,而不仅仅是纯字符串。在这些对象中,您可以拥有字符串、图标和一个布尔属性,用于描述该项目是否被选中。点击时,您更改列表以更新布尔属性上的相应项目,如果您在状态上有该列表,它将刷新列表并仅显示已选择的一项。

目的:

class MyObject {
   IconData icon;
   bool selected;
   String text;

   MyObject(this.icon, this.selected, this.text);
}

列表:

List<MyObject> moodIcons = <MyObject>[
    MyObject(Icons.mood_bad, "Bad mood", false),
    MyObject(Icons.sentiment_very_dissatisfied, "Very sad", false),
];

ListView.builder:

ListView.builder(
    itemCount: moodIcons.length,
    shrinkWrap: true,
    scrollDirection: Axis.horizontal,
    itemBuilder: (context, index) {
        Color iconColor;
        if(moodIcons.selected) {
            iconColor = Colors.green;
        } else {
            iconColor = Colors.gray;
        }

        return GestureDetector(
            child: Emotions(
                icon: Icon(
                    moodIcons[index].icon,
                    color: iconColor,
                ),
                textIcon: textIcons[index].text,
            ),
            onTap: () {
                for(int i = 0; i < moodIcons.length ; i++) {
                   if(i == index) {
                       moodIcons[i].selected = !moodIcons[i].selected;
                   } else if(moodIndex[i].selected) {
                       moodIcons[i].selected = false;
                   }
                }
                setState(() {});
            }
        );
    }),

推荐阅读