flutter 如何使变量与无状态小部件进行本地而非全局交互

mi7gmzs6  于 2023-01-06  发布在  Flutter
关注(0)|答案(1)|浏览(147)

我创建了一个无状态小部件,调用buttonTest.,然后将其合并到另一个无状态小部件ButtonList.中,该小部件随后显示在主有状态小部件中。我正在深入到ButtonTest小部件的变量是一个onTap,因此我可以将有状态小部件中的String的状态设置为按钮被按下时的名称。我也有一个布尔与隐藏按钮的预期用途,一旦它已被按下,所以只显示其余的选项。

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),
          ),
        ),
      ),
    );
  }
}

我遇到的问题是,当按钮被按下时,它会关闭所有按钮的可见性。
是否有可能让它工作而不必为每个按钮创建单独的变量,并且还将buttonTest和Buttonlist保持为无状态小部件?
非常感谢

r7s23pms

r7s23pms1#

一种方法是将ButtonList需要的参数存储在List中。点击后,从列表中删除该项目,并在主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));
                  }),
            );
          }),
    );
  }
}

相关问题