【问题标题】:Flutter overlayEntry doesn't update content after state changeFlutter overlayEntry 在状态改变后不更新内容
【发布时间】:2022-12-18 23:12:20
【问题描述】:

我正在尝试为文本字段实现覆盖功能,该功能根据用户输入的内容显示某些特定状态。当用户点击文本字段时,它会显示一个叠加层,在用户书写时应该显示一些信息,就像网络浏览器上的搜索栏一样。

我的问题是 OverlayEntry 的内容不会在用户输入更改的同时更新,它只会在我重新打开 Overlay 时更改。

预期行为

当前行为

为了测试此功能,我只是将相同的值从文本字段传递到叠加层。

这是我的代码:

家庭班

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
        child: Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  CustomTextField(),
                ]),
            // This trailing comma makes auto-formatting nicer for build methods.
          ),
        ));
  }
}

自定义文本字段类:

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

  @override
  State<CustomTextField> createState() => _CustomTextFieldState();
}

class _CustomTextFieldState extends State<CustomTextField>
    with TickerProviderStateMixin {
  TextEditingController controlador = TextEditingController();
  FocusNode nodeUno = FocusNode();
  OverlayEntry? _overlayEntry;
  GlobalKey globalKey = GlobalKey();
  final LayerLink _layerLink = LayerLink();
  String inputText = '';

  @override
  void initState() {
    super.initState();
    OverlayState? overlayState = Overlay.of(context);
    WidgetsBinding.instance!.addPostFrameCallback((_) {
      globalKey;
    });

    nodeUno.addListener(() {
      if (nodeUno.hasFocus) {
        _overlayEntry = _createOverlay(inputText);

        overlayState!.insert(_overlayEntry!);
      } else {
        _overlayEntry!.remove();
      }
    });
  }

  OverlayEntry _createOverlay([String? text]) {
    RenderBox renderBox = context.findRenderObject() as RenderBox;

    var size = renderBox.size;
    return OverlayEntry(
        builder: (context) => Positioned(
              width: size.width,
              child: CompositedTransformFollower(
                link: _layerLink,
                showWhenUnlinked: false,
                offset: Offset(0.0, size.height + 5.0),
                child: Material(
                  elevation: 5.0,
                  child: Column(
                    children: [
                      ListTile(
                        title: text != '' ? Text(text!) : const Text('data'),
                      ),
                    ],
                  ),
                ),
              ),
            ));
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 250,
      child: CompositedTransformTarget(
        link: _layerLink,
        child: TextField(
          focusNode: nodeUno,
          controller: controlador,
          onChanged: (value) {
            print(value);
            setState(() {
              inputText = value;
            });
          },
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: flutter state overlay


    【解决方案1】:

    好吧,据我所知,更新覆盖条目内容的唯一方法是删除并再次插入该条目,所以这就是我发现的有效方法:

    class CustomTextField extends StatefulWidget {
      CustomTextField({Key? key}) : super(key: key);
    
      @override
      State<CustomTextField> createState() => _CustomTextFieldState();
    }
    
    class _CustomTextFieldState extends State<CustomTextField>
        with TickerProviderStateMixin {
      TextEditingController controlador = TextEditingController();
      FocusNode nodeUno = FocusNode();
      OverlayEntry? _overlayEntry;
      GlobalKey globalKey = GlobalKey();
      final LayerLink _layerLink = LayerLink();
      String inputText = '';
      OverlayState? overlayState;
      bool popoverOpened = false;
    
      @override
      void initState() {
        super.initState();
        _overlayEntry = null;
        overlayState = Overlay.of(context);
        WidgetsBinding.instance!.addPostFrameCallback((_) {
          globalKey;
        });
    
        nodeUno.addListener(() {
          if (nodeUno.hasFocus) {
            _overlayEntry = _createOverlay(inputText);
            overlayState!.insert(_overlayEntry!);
          } else {
            if (_overlayEntry != null) {
              _overlayEntry?.remove();
              _overlayEntry = null;
            }
          }
        });
      }
    
      OverlayEntry _createOverlay([String? text]) {
        RenderBox renderBox = context.findRenderObject() as RenderBox;
    
        if (_overlayEntry != null && popoverOpened) {
          _overlayEntry!.remove();
        }
        popoverOpened = true;
        var size = renderBox.size;
        return OverlayEntry(
            builder: (context) => Positioned(
                  width: size.width,
                  child: CompositedTransformFollower(
                    link: _layerLink,
                    showWhenUnlinked: false,
                    offset: Offset(0.0, size.height + 5.0),
                    child: OverlayClass(val: inputText),
                  ),
                ));
      }
    
      @override
      Widget build(BuildContext context) {
        return SizedBox(
          width: 250,
          child: CompositedTransformTarget(
            link: _layerLink,
            child: TextField(
              focusNode: nodeUno,
              controller: controlador,
              onChanged: (value) {
                print(value);
                setState(() {
                  inputText = value;
                  _overlayEntry = _createOverlay(inputText);
                  overlayState!.insert(_overlayEntry!);
                });
              },
            ),
          ),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-03
      • 2023-04-09
      • 2021-04-05
      • 2016-10-02
      • 2021-08-11
      • 2019-11-30
      • 1970-01-01
      • 2018-12-18
      相关资源
      最近更新 更多