Home > OS >  How to change the background color of an item in a list when using the function List.generate in flu
How to change the background color of an item in a list when using the function List.generate in flu

Time:07-30

function description: when an item is clicked, change the background color of this item 。

I defined the variable color in the List.generate function and used the setState function in onTapDown to modify this value, but it has no effect. what should I do?

my code is as follows

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class Homepage extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Homepage> {
  final titles = ["AAA", "BBB", "CCC", "DDD"];
  final subtitles = [
    "我去,额度这么高?",
    "XX,你上次给我兑换的烤箱还不错哦",
    "抱歉,我觉得我们不是很合适",
    "邻居你好,你家的租户最近有点吵"
  ];
  final date = ["昨天 18:08", "星期二", "7月21日", "7月19日"];
  final avatar = [
    "WechatIMG325.jpeg",
    "WechatIMG326.jpeg",
    "WechatIMG327.jpeg",
    "WechatIMG328.jpeg"
  ];
  // final icons = [Icons.ac_unit, Icons.access_alarm, Icons.access_time];
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ...List.generate(titles.length, (index) {
          var color = Colors.white;
          return GestureDetector(
            behavior: HitTestBehavior.opaque,
            onTapDown: (TapDownDetails details) {
              setState(() {
                color = Colors.grey;
              });
              debugPrint("presed GestureDetector");
            },
            onTapUp: (TapUpDetails details) {
              setState(() {
                color = Colors.white;
              });
              debugPrint("presed GestureDetector");
            },
            child: Container(
              color: color,
              margin: const EdgeInsets.fromLTRB(10, 0, 10, 0),
              child: Row(children: [
                SizedBox(
                  width: 50,
                  child: Container(
                    margin: const EdgeInsets.fromLTRB(0, 10, 0, 10),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(5.0),
                      child: Image.asset("assets/images/${avatar[index]}",
                          height: 50, width: 50),
                    ),
                  ),
                ),
                //const SizedBox(width: 10),
                IntrinsicWidth(
                  child: Container(
                    margin: const EdgeInsets.fromLTRB(10, 0, 0, 0),
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: [
                        Text(
                          titles[index],
                          style: const TextStyle(
                            fontSize: 18,
                            color: Colors.black,
                            fontWeight: FontWeight.w300,
                          ),
                        ),
                        const SizedBox(height: 5),
                        Text(
                          subtitles[index],
                          style: const TextStyle(
                            fontSize: 15,
                            color: Colors.black54,
                            fontWeight: FontWeight.w300,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ]),
            ),
          );
        }),
      ],
    );
  }
}

CodePudding user response:

try this code will help you to start in OOP and make model to data in your app and you can add any thing to class like Icon ....

        class FakeData {
    final String title, subTitle, avatar, data;
    bool onTapDown;

   FakeData(
   {required this.title,
   this.onTapDown = false,
   required this.subTitle,
   required this.avatar,
   required this.data});
    }

this class collect data app and state for all item

        class HomeState extends State<Homepage> {
      final fakeData = [
        FakeData(
          title: 'AAA',
          subTitle: '我去,额度这么高?',
          avatar: "WechatIMG325.jpeg",
          data: "昨天 18:08",
        ),
        FakeData(
          title: 'BBB',
          subTitle: "XX,你上次给我兑换的烤箱还不错哦",
          avatar: "WechatIMG326.jpeg",
          data: "星期二",
        ),
        FakeData(
          title: 'CCC',
          subTitle: "抱歉,我觉得我们不是很合适",
          avatar: "WechatIMG327.jpeg",
          data: "7月21日",
        ),
        FakeData(
          title: 'DDD',
          subTitle: "邻居你好,你家的租户最近有点吵",
          avatar: "WechatIMG328.jpeg",
          data: "7月19日",
        ),
      ];
    
      // final icons = [Icons.ac_unit, Icons.access_alarm, Icons.access_time];
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            ...List.generate(fakeData.length, (index) {
              return GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTapDown: (TapDownDetails details) {
                  setState(() {
                    fakeData[index].onTapDown = !fakeData[index].onTapDown;
                  });
                  debugPrint("presed GestureDetector");
                },
                onTapUp: (TapUpDetails details) {
                  setState(() {
                    fakeData[index].onTapDown = !fakeData[index].onTapDown;
                  });
                  debugPrint("presed GestureDetector");
                },
                child: Container(
                  color: fakeData[index].onTapDown ? Colors.grey : Colors.white,
                  margin: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                  child: Row(children: [
                    SizedBox(
                      width: 50,
                      child: Container(
                        margin: const EdgeInsets.fromLTRB(0, 10, 0, 10),
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(5.0),
                          child: Image.asset(
                              "assets/images/${fakeData[index].avatar}",
                              height: 50,
                              width: 50),
                        ),
                      ),
                    ),
                    //const SizedBox(width: 10),
                    IntrinsicWidth(
                      child: Container(
                        margin: const EdgeInsets.fromLTRB(10, 0, 0, 0),
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [
                            Text(
                              fakeData[index].title,
                              style: const TextStyle(
                                fontSize: 18,
                                color: Colors.black,
                                fontWeight: FontWeight.w300,
                              ),
                            ),
                            const SizedBox(height: 5),
                            Text(
                              fakeData[index].subTitle,
                              style: const TextStyle(
                                fontSize: 15,
                                color: Colors.black54,
                                fontWeight: FontWeight.w300,
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ]),
                ),
              );
            }),
          ],
        );
      }
    }

CodePudding user response:

The variable color needs to be outside the build method of the State, this code will reset the color to Colors.white on each build.

import 'package:flutter/material.dart';

class Homepage extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Homepage> {
  final titles = ["AAA", "BBB", "CCC", "DDD"];
  final subtitles = [
    "我去,额度这么高?",
    "XX,你上次给我兑换的烤箱还不错哦",
    "抱歉,我觉得我们不是很合适",
    "邻居你好,你家的租户最近有点吵"
  ];
  final date = ["昨天 18:08", "星期二", "7月21日", "7月19日"];
  final avatar = [
    "WechatIMG325.jpeg",
    "WechatIMG326.jpeg",
    "WechatIMG327.jpeg",
    "WechatIMG328.jpeg"
  ];
  var color = Colors.white;

  // final icons = [Icons.ac_unit, Icons.access_alarm, Icons.access_time];
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ...List.generate(titles.length, (index) {
          return GestureDetector(
            behavior: HitTestBehavior.opaque,
            onTapDown: (TapDownDetails details) {
              setState(() {
                color = Colors.grey;
              });
              debugPrint("presed GestureDetector");
            },
            onTapUp: (TapUpDetails details) {
              setState(() {
                color = Colors.white;
              });
              debugPrint("presed GestureDetector");
            },
            child: Container(
              color: color,
              margin: const EdgeInsets.fromLTRB(10, 0, 10, 0),
              child: Row(children: [
                SizedBox(
                  width: 50,
                  child: Container(
                    margin: const EdgeInsets.fromLTRB(0, 10, 0, 10),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(5.0),
                      child: Image.asset("assets/images/${avatar[index]}",
                          height: 50, width: 50),
                    ),
                  ),
                ),
                //const SizedBox(width: 10),
                IntrinsicWidth(
                  child: Container(
                    margin: const EdgeInsets.fromLTRB(10, 0, 0, 0),
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: [
                        Text(
                          titles[index],
                          style: const TextStyle(
                            fontSize: 18,
                            color: Colors.black,
                            fontWeight: FontWeight.w300,
                          ),
                        ),
                        const SizedBox(height: 5),
                        Text(
                          subtitles[index],
                          style: const TextStyle(
                            fontSize: 15,
                            color: Colors.black54,
                            fontWeight: FontWeight.w300,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ]),
            ),
          );
        }),
      ],
    );
  }
}

The code above should work as our state is extracted outside of the build method and it would update correctly with each setState.

  • Related