Home > Mobile >  how to get a variable to interact with a stateless widget locally not globally
how to get a variable to interact with a stateless widget locally not globally

Time:01-04

I've created a stateless widget call buttonTest. which is then incoroprated into another stateless widget called ButtonList. which is then displayed in the main stateful widget. the variables I'm drilling down to the ButtonTest widget are an onTap so I can set the state of a String in my Stateful Widget to the name of the button when it is pressed. I also have a bool with the intended use of hiding the button once it has been pushed so only the remaining options are displayed.

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

  @override
  State<TestTest> createState() => _TestTestState();
}

class _TestTestState extends State<TestTest> {
  bool isChecked = true;
  String text = '';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          SizedBox(
            height: 50,
          ),
          ButtonsList(
              onTap: (val) {
                setState(
                  () {
                    text = val;
                    print(text);
                    isChecked =
                        false; // what do I need to do here to only have the bool effect the visibility in each button so when a button is pressed, that button disappears. at the moment, when a button is pressed, they all disappear.
                  },
                );
              },
              visible: isChecked)
        ],
      ),
    );
  }
}

class ButtonsList extends StatelessWidget {
  ButtonsList({required this.onTap, required this.visible});

  final ValueChanged? onTap;
  final bool visible;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Faction(FactionText: 'Options:'),
        SizedBox(
          height: 10,
        ),
        ButtonTest(visible: visible, text: 'option A', onTap: onTap),
        SizedBox(
          height: 10,
        ),
        ButtonTest(visible: visible, text: 'option B', onTap: onTap),
        SizedBox(
          height: 10,
        ),
        ButtonTest(visible: visible, text: 'option C', onTap: onTap),
        SizedBox(
          height: 10,
        ),
        ButtonTest(visible: visible, text: 'option D', onTap: onTap),
        SizedBox(
          height: 10,
        ),
        ButtonTest(visible: visible, text: 'option E', onTap: onTap),
        SizedBox(
          height: 10,
        ),
        ButtonTest(visible: visible, text: 'option F', onTap: onTap),
        SizedBox(
          height: 10,
        ),
      ],
    );
  }
}

class ButtonTest extends StatelessWidget {
  ButtonTest({required this.text, required this.onTap, required this.visible});

  final String text;
  final ValueChanged? onTap;
  final bool visible;

  @override
  Widget build(BuildContext context) {
    return Visibility(
      visible: visible,
      child: Container(
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(5),
          color: Colors.blueGrey,
        ),
        child: ListTile(
          onTap: () {
            if (onTap != null) {
              onTap!(text);
            }
          },
          title: Text(
            text,
            style: TextStyle(
                fontSize: 15,
                fontFamily: 'SourceSansPro',
                fontWeight: FontWeight.bold),
          ),
        ),
      ),
    );
  }
}

The problem I'm having is when the button is pressed, it turns off the visibility on all the buttons.

is it possible to get it to work without having to create a separate variable for each of the buttons and also to keep the buttonTest and Buttonlist as stateless widgets?

thanks so much

CodePudding user response:

One way would be to store parameters that ButtonList needs in a List. When tapped remove that item from list and show it wherever you want inside the main Stateful widget.

class TestWidget extends StatefulWidget {
  const TestWidget({super.key});

  @override
  State<TestWidget> createState() => _TestWidgetState();
}

class _TestWidgetState extends State<TestWidget> {
  var options = [];

  String value = '';

  @override
  void initState() {
    options = ['A', 'B', 'C', 'D', 'E'];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Selected $value')),
      body: ListView.builder(
          itemCount: options.length,
          shrinkWrap: true,
          itemBuilder: (context, i) {
            return Padding(
              padding: const EdgeInsets.all(4.0),
              child: ListTile(
                  tileColor: Colors.blue[200],
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                  title: Text('Option ${options[i]}'),
                  onTap: () {
                    setState(() => value = options.removeAt(i));
                  }),
            );
          }),
    );
  }
}
  • Related