Home > Back-end >  How to select a single container in a list of containers with flutter?
How to select a single container in a list of containers with flutter?

Time:11-13

I am trying to build an inventory system with flutter by creating a list of containers but I am having an issue where whenever I try to change the background of a single container (marking it as selected) it changes the border of all the containers. Is there a way to make the variable, borderColor only change the border of the tapped container?

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Color borderColor = Colors.black;

  @override
  Widget build(BuildContext context) {
    var n = 5;
    var listOfContainers = <Padding>[];
    var list = List<int>.generate(n, (i) => i   1);
    list.forEach((i) {

      return listOfContainers.add(
        Padding(
          padding: const EdgeInsets.all(10),
          child: Container(
            width: 100,
            height: 100,
            decoration: BoxDecoration(
                color: Colors.brown,
                border: Border.all(width: 3, color: borderColor),
                borderRadius: const BorderRadius.all(Radius.circular(5))),
            child: InkWell(
              onTap: () {
                setState(() {
                  borderColor = Colors.white;
                  print(i);
                });
              },
            ),
          ),
        ),
      );
    });

    return Scaffold(
      appBar: AppBar(
        title: Text('test app'),
      ),
      body: Center(
        child: Column(
          children: [
            Row(mainAxisAlignment: MainAxisAlignment.center, children: listOfContainers)
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

CodePudding user response:

Just try like this

class _MyHomePageState extends State<MyHomePage> {
  
  int selected_inx = 0; // set it -1 if you want by default all unselected. 
  @override
  Widget build(BuildContext context) {
    var n = 5;
    var listOfContainers = <Padding>[];
    var list = List<int>.generate(n, (i) => i   1);
    list.forEach((i) {
    Color borderColor = (i == selected_inx) ? Colors.white : Colors.black;
      return listOfContainers.add(
        Padding(
          padding: const EdgeInsets.all(10),
          child: Container(
            width: 100,
            height: 100,
            decoration: BoxDecoration(
                color: Colors.brown,
                border: Border.all(width: 3, color: borderColor),
                borderRadius: const BorderRadius.all(Radius.circular(5))),
            child: InkWell(
              onTap: () {
                setState(() {
                  selected_inx = i;
                  print(i);
                });
              },
            ),
          ),
        ),
      );
    });

    return Scaffold(
      appBar: AppBar(
        title: Text('test app'),
      ),
      body: Center(
        child: Column(
          children: [
            Row(mainAxisAlignment: MainAxisAlignment.center, children: listOfContainers)
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

CodePudding user response:

This is not a different answer but a more optimized version of the below. You don't need to have two lists. You can use the List.generate function directly with listOfContainers:

final n = 5;
final listOfContainers = List<Padding>.generate(
  n,
  (i) {
    final inx = i   1;
    final borderColor = (inx == selected_inx) ? Colors.white : Colors.black;
    return Padding(
      padding: const EdgeInsets.all(10),
      child: Container(
        width: 100,
        height: 100,
        decoration: BoxDecoration(
          color: Colors.brown,
          border: Border.all(width: 3, color: borderColor),
          borderRadius: const BorderRadius.all(Radius.circular(5)),
        ),
        child: InkWell(
          onTap: () {
            setState(() {
              selected_inx = i;
              print(i);
            });
          },
        ),
      ),
    );
  },
  growable: false,
);
  • Related