繁体   English   中英

颤振:CheckBox在OverlayEntry中不起作用?

[英]Flutter: CheckBox doesn't work inside OverlayEntry?

我试图在OverlayEntry中显示一些小部件,如CheckBox或Switch。 叠加层是在点击事件中构建的。 问题是bool _value仅在我第一次点击叠加层内的CheckBox时更新,但CheckBox不会更新其状态。 奇怪的是(只有第一次点击)点击更新覆盖层外的CheckBox而不是其中的CheckBox。 我错过了什么?

下面是一个完整的片段来重现这一点。

谢谢你的时间!

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

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

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _value = true;

  _buildOverlay() {
    OverlayEntry _overlayEntry;
    OverlayState _overlayState = Overlay.of(context);

    _overlayEntry = OverlayEntry(
      builder: (BuildContext context) {
        return Stack(
          children: <Widget>[
            Material(
              child: Container(
                padding: EdgeInsets.all(100),
                color: Colors.lightBlue,
                child: Checkbox(
                  value: _value,
                  onChanged: (bool value) { print("$value  $_value"); setState(() => _value = value); },
                ),
              ),
            ),
          ],
        );
      },
    );

    _overlayState.insert(_overlayEntry);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(""),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Row(
              children: <Widget>[
                FloatingActionButton(
                  onPressed: () {_buildOverlay();},
                  child: Icon(Icons.add),
                ),
                Checkbox(
                  value: _value,
                  onChanged: (bool value) { print("$value  $_value"); setState(() => _value = value); },
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

更新:

除了anmol.majhail解决方案之外,使用ValueListenableBuilder可以是另一种解决方案而无需执行StatefulWidget。

_value的声明变为: var _value = ValueNotifier<bool>(false);

这里是_buildOverlay()函数中的_overlayEntry:

_overlayEntry = OverlayEntry(
      builder: (BuildContext context) {
        return Material(
          child: Container(
            padding: EdgeInsets.all(100),
            color: Colors.lightBlue,
            child: ValueListenableBuilder<bool>(
              valueListenable: _value,
              builder: (context, value, child) {
                return Checkbox(
                    value: _value.value,
                    onChanged: (bool value) { 
                      print("$value  $_value"); 
                      setState(() => _value.value = value); 
                    },
                  );
              },
            ),
          ),
        );
      },
    );

这里的问题是Overlay entry有不同的上下文。 为了使其工作,您需要在单独的stateful窗口小部件中分隔overlay entry - 通过它可以管理checkbox状态。

工作代码:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

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

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _value = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(""),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Row(
              children: <Widget>[
                FloatingActionButton(
                  onPressed: () {
                    OverlayState _overlayState = Overlay.of(context);
                    _overlayState.insert(OverlayEntry(
                      builder: (BuildContext context) {
                        return OverlayClass(
                          val: _value,
                        );
                      },
                    ));
                    // _buildOverlay(context);
                  },
                  child: Icon(Icons.add),
                ),
                Checkbox(
                  value: _value,
                  onChanged: (bool value) {
                    print("$value  $_value");
                    setState(() => _value = value);
                  },
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class OverlayClass extends StatefulWidget {
  final bool val;

  OverlayClass({this.val});

  @override
  _OverlayClassState createState() => _OverlayClassState();
}

class _OverlayClassState extends State<OverlayClass> {
  bool _value;
  @override
  void initState() {
    super.initState();
    _value = widget.val;
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Material(
          child: Container(
            padding: EdgeInsets.all(100),
            color: Colors.lightBlue,
            child: Checkbox(
              value: _value,
              onChanged: (bool value) {
                print("$value  $_value");
                setState(() => _value = value);
              },
            ),
          ),
        ),
      ],
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM