Flutter入门(28):Flutter 组件之 FocusNode 详解

1. 基本介绍

FocusNode 主要提供焦点控制功能。

2. 示例代码

代码下载地址。如果对你有帮助的话记得给个关注,代码会根据我的 Flutter 专题不断更新。

3. FocusNode 详解

3.1 容器创建

我们先创建一个最简单的可收起或者隐藏键盘的控件,在点击完成按钮时收起键盘。

import 'package:flutter/material.dart';

class FMFocusNodeVC extends StatefulWidget {
  @override
  FMFocusNodeState createState() => FMFocusNodeState();
}

class FMFocusNodeState extends State <FMFocusNodeVC> {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text('FocusNode'),),
      body: _normalField(),
    );
  }

  TextField _normalField(){
    FocusNode normalNode = FocusNode();

    return TextField(
      focusNode: normalNode,
      onSubmitted: (string){
        print(string);
        // normalNode.unfocus();
        FocusManager.instance.primaryFocus.unfocus();
      },
    );
  }
}
FocusNode normal.gif

以下两种方式均可隐藏键盘。

normalNode.unfocus(); // 拿到对应的 FocusNode

FocusManager.instance.primaryFocus.unfocus();

3.2 自动跳转焦点

我们使用 FocusScope 控件,以及 FocusScopeNode 来对焦点进行管理。话不多说,直接上代码。

import 'package:flutter/material.dart';

class FMFocusNodeVC extends StatefulWidget {
  @override
  FMFocusNodeState createState() => FMFocusNodeState();
}

class FMFocusNodeState extends State <FMFocusNodeVC> {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text('FocusNode'),),
      // body: _normalField(),
      body: _focusScope(),
    );
  }

  FocusScopeNode _scopeNode = FocusScopeNode();

  FocusScope _focusScope(){
    return FocusScope(
      node: _scopeNode,
      child: ListView(
        padding: EdgeInsets.all(20),
        children: [
          _textField(),
          _textField(),
          _textField(),
          _btnField(),
          _textField(),
          _btnField(),
          _textField(),
          _textField(),
        ],
      ),
    );
  }

  TextField _textField(){
    return TextField(
      decoration: InputDecoration(
        hintText: "请输入文本"
      ),
      onEditingComplete: (){
        _scopeNode.nextFocus();
      },
    );
  }

  Row _btnField(){
    return Row(
      children: [
        Expanded(child: _textField()),
        RaisedButton(
          onPressed: (){},
          child: Text("我可以点的"),
        )
      ],
    );
  }

  TextField _normalField(){
    FocusNode normalNode = FocusNode();

    return TextField(
      focusNode: normalNode,
      onSubmitted: (string){
        print(string);
        // normalNode.unfocus();
        FocusManager.instance.primaryFocus.unfocus();
      },
    );
  }
}

其实这里已经实现了光标自动下跳的功能了,但是在 flutter 中很多子控件其实也有 focusNode 属性,与 TextField 一样。在这里 FocusScopeNode 就一视同仁了,认为他也是可以聚焦的一份子,所以有时候会卡在某一个不是 TextField 的控件上。

FocusNode error.gif

3.3 跳过部分控件的 FocusNode

设置 skipTraversal 属性,FocusScopeNode 会自动跳过设置为 true 的控件。

  Row _btnField(){
    return Row(
      children: [
        Expanded(child: _textField(false)),
        RaisedButton(
          onPressed: (){},
          focusNode: FocusNode(skipTraversal: true),
          child: Text("我可以点的"),
        )
      ],
    );
  }
Focus complete.gif

4. 技术小结

  • FocusNode 主要就是用来控制焦点,还算比较常用。
  • 熟练掌握键盘收起更为实用一点,其他部分可以有需要时再做了解。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容