检测窗口小部件何时更改Flutter中的位置

时间:2019-04-20 02:29:39

标签: dart flutter

有什么方法可以检测小部件何时更改位置?例如键盘弹出时和内容上移时?我想在不依靠焦点事件或尝试检测键盘状态的情况下进行检测。

这是一个示例应用程序:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: MyTextField()
        )
      )
    );
  }
}

class MyTextField extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return TextField();
  }

}

如何MyTextField聚焦时向上移动?

2 个答案:

答案 0 :(得分:1)

您可以使用WidgetsBindingObserver来检测指标何时更改,这里有一个示例,但是您必须使用GlobalKey来检查Widget的新位置:

    class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
      GlobalKey _key = GlobalKey();

      @override
      void initState() {
        WidgetsBinding.instance.addObserver(this);
        super.initState();
      }

      @override
      void dispose() {
        WidgetsBinding.instance.removeObserver(this);
        super.dispose();
      }

      @override
      void didChangeMetrics() {
        final RenderBox renderBox = _key.currentContext.findRenderObject();
        final position = renderBox.localToGlobal(Offset.zero);
        print("position : ${position.dx},${position.dy}");
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: MyTextField(
              key: _key,
            ),
          ),
        );
      }
    }

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

      @override
      Widget build(BuildContext context) {
        return TextField();
      }
    }

答案 1 :(得分:0)

如果您只是想知道键盘是否可见,可以使用以下方法:

import 'dart:ui';

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeMetrics() {
    print('Is the keyboard visible? ${window.viewInsets.bottom != 0 ? 'yes' : 'no'}');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: TextField(),
        ),
      ),
    );
  }
}

说明:通过获取绘制应用程序所在的矩形的底部位置,可以推断出系统组件是否减小了应用程序的空间,因此是否可以看到键盘。

这仅回答您问题的这一部分:

  

例如当键盘弹出并且内容向上移动时?

但是,至少绘制您的应用程序的矩形的大小始终是当前大小,而不是旧大小。这是@diegoveloper答案的问题,您总是能获得TextField的旧位置。