0

Im trying to build dynamically generated widgets, each of them need to be selected/highlighted when I tap on them.

here is code borrowed by another solution on stackoverflow, reference code below is DartPad friendly to paste and play.

this is perfect solution for me except, I don't want hard coded integer to identify which widget is tapped on ( I don't have finite number of widget), instead need to check against key or unique key property of myContainer instance

import 'package:flutter/material.dart';


void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.light(),
      debugShowCheckedModeBanner: false,
      home:  HomeScreen(),
    );
  }
}


class MyContainer extends StatelessWidget {
  final VoidCallback ontap;
  bool isSelected;
  Key myKey = UniqueKey();
  MyContainer({
    required this.ontap,
    this.isSelected = false,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(10),
      child: GestureDetector(
        onTap: ontap,
        child: Container(
          decoration: BoxDecoration(
            color: Colors.grey.shade300,
            borderRadius: BorderRadius.circular(20),
            border: isSelected == true
                ? Border.all(width: 2, color: Colors.blue)
                : null,
          ),
        ),
      ),
    );
  }
}

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int? selectedIndex;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Expanded(
              child: Row(
            children: [
              Expanded(
                child: MyContainer(
                  isSelected: selectedIndex == 1,
                  ontap: () {
                    selectedIndex = 1;
                    setState(() {});
                  },
                ),
              ),
              Expanded(
                child: MyContainer(
                  isSelected: selectedIndex == 2,
                  ontap: () {
                    selectedIndex = 2;
                    setState(() {});
                  },
                ),
              )
            ],
          )),
          Expanded(
            child: MyContainer(
              isSelected: selectedIndex == 3,
              ontap: () {
                selectedIndex = 3;
                setState(() {});
              },
            ),
          ),
        ],
      ),
    );
  }
} ```
Shreyz
  • 99
  • 1
  • 10

1 Answers1

0

you can use the spread operator ... to generate widgets dynamically based on your needs elements length, and use the index for each one :

inside the Column children:

Column(
children: <Widget>[
 ...List.generate(100, (index) =>
     Expanded(
            child: MyContainer(
              isSelected: selectedIndex == index,
              ontap: () {
                selectedIndex = index;
                setState(() {});
              },
            ),
          )
        ],
      )),),],),

this will basically generate 100 widgets, each of them having an index from 0-99. if you have an already List of your data, you can use its length instead of hardcoded 100, so it will be dynamic.

Gwhyyy
  • 7,554
  • 3
  • 8
  • 35
  • my widgets neither in a list nor siblings of same parents, they may be anywhere in the tree. they are generated dynamically though. I appreciate for your effort to think about it. – Shreyz Nov 04 '22 at 13:22