美文网首页Flutter圈子安卓开发相关flutter
Flutter点击空白隐藏键盘的全局做法

Flutter点击空白隐藏键盘的全局做法

作者: A_si | 来源:发表于2020-11-25 21:38 被阅读0次

    开发原生页面的时候,在处理键盘事件上,通常的需求是,点击输入框外屏幕,要隐藏键盘,同样的,这样的需求也需要在 Flutter 上实现,

    Android 上的实现方式是在基类 Activity 里实现事件分发,判断触摸位置是否在输入框内。

      /**
         * 获取点击事件
         */
        @CallSuper
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            if (ev.getAction() == MotionEvent.MotionEvent ) {
                View view = getCurrentFocus();
                if (isShouldHideKeyBord(view, ev)) {
                    hideSoftInput(view.getWindowToken());
                }
            }
            return super.dispatchTouchEvent(ev);
        }
    
        /**
         * 判定当前是否需要隐藏
         */
        protected boolean isShouldHideKeyBord(View v, MotionEvent ev) {
            if (v != null && (v instanceof EditText)) {
                int[] l = {0, 0};
                v.getLocationInWindow(l);
                int left = l[0], top = l[1], bottom = top + v.getHeight(), right = left + v.getWidth();
                return !(ev.getX() > left && ev.getX() < right && ev.getY() > top && ev.getY() < bottom);
            }
            return false;
        }
    
        /**
         * 隐藏软键盘
         */
        private void hideSoftInput(IBinder token) {
            if (token != null) {
                InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                manager.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
    

    那么在 Flutter 上如何实现呢?

    许多文章的做法如下,每个包含TextField的屏幕中包裹GestureDetector,手动控制Focus。一旦失去焦点,就请求关闭键盘。这是一个临时的解决方案,容易出错,并且生成大量代码。

    GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: () {
            // 触摸收起键盘
            FocusScope.of(context).requestFocus(FocusNode());
        },
        child: *******
    }
    
    

    通常这种需求是对应整个 app 的,有没有一劳永逸的方法呢?当然有,我们可以借助MaterialAppbuilder方法,在 Navigator上方但在其他小部件下方插入小部件,仅添加了一个“全局” GestureDetector,它将为我们处理键盘关闭:

    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          builder: (context, child) => Scaffold(
            // Global GestureDetector that will dismiss the keyboard
            body: GestureDetector(
              onTap: () {
             hideKeyboard(context);
              },
              child: child,
            ),
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    
      void hideKeyboard(BuildContext context) {
        FocusScopeNode currentFocus = FocusScope.of(context);
        if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
          FocusManager.instance.primaryFocus.unfocus();
        }
      }
    }
    
    1.gif

    当然也可以使用下面这个方法关闭键盘:

    SystemChannels.textInput.invokeMethod(
    'TextInput.hide');
    

    这样就全局控制,再也不用在每个页面写了。

    相关文章

      网友评论

        本文标题:Flutter点击空白隐藏键盘的全局做法

        本文链接:https://www.haomeiwen.com/subject/ejkiiktx.html