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  {
  @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  {
  @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 主要就是用来控制焦点,还算比较常用。
  • 熟练掌握键盘收起更为实用一点,其他部分可以有需要时再做了解。

你可能感兴趣的:(Flutter入门(28):Flutter 组件之 FocusNode 详解)