如何为选定的 ListItem onTap 着色

How to color selected ListItem onTap

我想像这样为 ListView 中的 select 值着色:

问题是我尝试打印所有内容,代码:

class _ProcedureList extends State<ProcedureList> {

bool isSelected  = true;

   _isSelected() {
    setState(() {
      if (isSelected) {
        isSelected = false;
      } else {
        isSelected = true;
      }
    });
  }



  @override
  Widget build(BuildContext context) {
    var procedureList = widget.filteredkits
        .where((kit) => kit.brand == widget.brand)
        .map((kit) => kit.procedure)
        .toSet()
        .toList();

    return Expanded(
      flex: 2,
      child: Container(
        padding: EdgeInsets.only(left: 35.0),
        child: new ListView.builder(
          itemCount: procedureList.length,
          itemBuilder: (BuildContext context, int index) {
            return Padding(
              padding: EdgeInsets.all(6.0),
              child: Column(
                children: <Widget>[
                  new Container(
                    width: 300.0,
                    height: 30.0,
                    color: Colors.grey[700],
                    padding: EdgeInsets.all(6.0),
                    child: new Text(widget.brand),
                  ),
                  GestureDetector(
                    onTap: () => widget.getProcedureSelectedandList(procedureList[index].toString()) & _isSelected(),
                    child: Container(
                      width: 300.0,
                      padding: EdgeInsets.all(3.0),
                      color: !isSelected ? Colors.white : Colors.orange,
                      child: 
                      new Text(procedureList[index])
                    ),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

这就是我的成就,全是彩色的:

我不知道如何在事件发生时只为一项着色,以及我们是否可以更好地更改同一事件的文本颜色。

您需要做的是重构您的代码,以便传递到 ListView builder 函数的小部件拥有它自己的 StatefulWidget。因此,将构建器函数内的小部件树移动到它自己单独的 StatefulWidget 中,并在那里处理状态操作逻辑而不是 ProcedureList。你得到这种行为的原因是因为从 ListView.builder 生成的每个实例都暴露在相同的状态值 isSelected 通过将你的逻辑移动到一个单独的 StatefulWidget 每个实例将有自己的状态。

您应该为列表中的每个项目设置一个 isSelected 值,然后当用户单击列表中的项目之一时,您将更改仅针对录音项目索引和构建中的 isSelected 值声明你应该根据传入索引

的 isSelected 值执行操作

这里是例子:

class MyListWidgetState extends State<MyListWidget> {
  List<String> items = ["A", "B", "C", "D", "E", "F"];

  Map<int, bool> itemsSelectedValue = Map();

  @override
  Widget build(BuildContext context) {
    return new ListView.builder(
        itemCount: items.length,
        itemBuilder: (context, index) {
          bool isCurrentIndexSelected = itemsSelectedValue[index] == null
              ? false
              : itemsSelectedValue[index];

          Container contianer;

          if (isCurrentIndexSelected) {
            contianer = new Container(
              alignment: Alignment.center,
              height: 100.0,
              color: Colors.blue,
              child: new Text(
                items[index],
                style: new TextStyle(color: Colors.red, fontSize: 18.0),
                textAlign: TextAlign.center,
              ),
            );
          } else {
            contianer = new Container(
              alignment: Alignment.center,
              height: 100.0,
              color: Colors.red,
              child: new Text(
                items[index],
                style: new TextStyle(color: Colors.blue, fontSize: 18.0),
                textAlign: TextAlign.center,
              ),
            );
          }

          return GestureDetector(
            onTap: () {
              print("${!isCurrentIndexSelected}");
              itemsSelectedValue[index] = !isCurrentIndexSelected;

              setState(() {
                print("OnClick : $index + ${itemsSelectedValue[index]}");
              });
            },
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: contianer,
            ),
          );
        });
  }
}

或者您可以创建 StateFull 小部件,它为列表中的每个项目保留自己的 isSelected 值,如下例所示:

List<String> items = [
  "A",
  "B",
  "C",
  "D",
  "E",
  "F",
  "D",
  "J",
  "K",
  "L",
  "M",
  "P"
];

class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new Scaffold(
          body: new ListView.builder(
        itemCount: items.length,
        itemBuilder: (context, index) {
          return new SelectableWidget(
            new SelectableWidgetViewModel(
              items[index],
              isSelected: false,
            ),
          );
        },
      )),
    );
  }
}

class SelectableWidget extends StatefulWidget {
  final SelectableWidgetViewModel viewModel;

  SelectableWidget(this.viewModel);

  @override
  State<StatefulWidget> createState() {
    return SelectableWidgetState();
  }
}

class SelectableWidgetState extends State<SelectableWidget> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    Container container;

    if (widget.viewModel.isSelected) {
      container = new Container(
        alignment: Alignment.center,
        height: 100.0,
        color: Colors.blue,
        child: new Text(
          widget.viewModel.title,
          style: new TextStyle(color: Colors.red, fontSize: 18.0),
          textAlign: TextAlign.center,
        ),
      );
    } else {
      container = new Container(
        alignment: Alignment.center,
        height: 100.0,
        color: Colors.red,
        child: new Text(
          widget.viewModel.title,
          style: new TextStyle(color: Colors.blue, fontSize: 18.0),
          textAlign: TextAlign.center,
        ),
      );
    }

    return GestureDetector(
      onTap: () {
        setState(() {
          widget.viewModel.isSelected = !widget.viewModel.isSelected;
        });
      },
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: container,
      ),
    );
  }
}

class SelectableWidgetViewModel {
  bool isSelected;
  String title;

  SelectableWidgetViewModel(this.title, {this.isSelected = false});
}

出于性能原因,我认为第二种选择更好

抱歉回复晚了。我有更好的解决方案,我已经更改了您的代码

    class _ProcedureList extends State<ProcedureList> {



        int isSelected  = -1; // changed bool to int and set value to -1 on first time if you don't select anything otherwise set 0 to set first one as selected. 


       _isSelected(int index) { //pass the selected index to here and set to 'isSelected'
        setState(() {
            isSelected = index;
        });
      }



      @override
      Widget build(BuildContext context) {
        var procedureList = widget.filteredkits
            .where((kit) => kit.brand == widget.brand)
            .map((kit) => kit.procedure)
            .toSet()
            .toList();

    return Expanded(
      flex: 2,
      child: Container(
        padding: EdgeInsets.only(left: 35.0),
        child: new ListView.builder(
          itemCount: procedureList.length,
          itemBuilder: (BuildContext context, int index) {
            return Padding(
              padding: EdgeInsets.all(6.0),
              child: Column(
                children: <Widget>[
                  new Container(
                    width: 300.0,
                    height: 30.0,
                    color: Colors.grey[700],
                    padding: EdgeInsets.all(6.0),
                    child: new Text(widget.brand),
                  ),
                  GestureDetector(
                    onTap: () => widget.getProcedureSelectedandList(procedureList[index].toString()) & _isSelected(index), //pass index value to '_isSelected' 
                    child: Container(
                      width: 300.0,
                      padding: EdgeInsets.all(3.0),
                      color: isSelected != null && isSelected == index //set condition like this. voila! if isSelected and list index matches it will colored as white else orange.
                             ? Colors.white 
                             : Colors.orange,
                      child: 
                      new Text(procedureList[index])
                    ),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

还是一头雾水check this blog