在这里插入图片描述

案例概述

FocusNode 用于管理 Widget 的焦点状态。本案例展示了如何使用 FocusNode。

核心概念

1. FocusNode 基础

FocusNode 管理焦点状态。

2. 焦点转移

可以在 Widget 之间转移焦点。

3. 焦点监听

可以监听焦点变化。

代码详解

示例 1:基础焦点

class BasicFocusExample extends StatefulWidget {
  
  State<BasicFocusExample> createState() => _BasicFocusExampleState();
}

class _BasicFocusExampleState extends State<BasicFocusExample> {
  late FocusNode _focusNode;

  
  void initState() {
    super.initState();
    _focusNode = FocusNode();
  }

  
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          focusNode: _focusNode,
          decoration: const InputDecoration(hintText: '输入文本'),
        ),
        ElevatedButton(
          onPressed: () {
            _focusNode.requestFocus();
          },
          child: const Text('获取焦点'),
        ),
      ],
    );
  }
}

代码解释: FocusNode 管理焦点状态。requestFocus() 将焦点转移到该输入框。必须在 dispose 中调用 dispose() 释放资源。

示例 2:焦点转移

class FocusTransferExample extends StatefulWidget {
  
  State<FocusTransferExample> createState() => _FocusTransferExampleState();
}

class _FocusTransferExampleState extends State<FocusTransferExample> {
  late FocusNode _focusNode1;
  late FocusNode _focusNode2;

  
  void initState() {
    super.initState();
    _focusNode1 = FocusNode();
    _focusNode2 = FocusNode();
  }

  
  void dispose() {
    _focusNode1.dispose();
    _focusNode2.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          focusNode: _focusNode1,
          decoration: const InputDecoration(hintText: '输入框1'),
        ),
        TextField(
          focusNode: _focusNode2,
          decoration: const InputDecoration(hintText: '输入框2'),
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            ElevatedButton(
              onPressed: () {
                _focusNode1.requestFocus();
              },
              child: const Text('焦点到输入框1'),
            ),
            ElevatedButton(
              onPressed: () {
                _focusNode2.requestFocus();
              },
              child: const Text('焦点到输入框2'),
            ),
          ],
        ),
      ],
    );
  }
}

代码解释: 多个 FocusNode 可独立管理多个输入框的焦点。通过 requestFocus() 在输入框间转移焦点。这在表单中很常见,如按 Tab 键转移焦点。

示例 3:焦点监听

class FocusListenerExample extends StatefulWidget {
  
  State<FocusListenerExample> createState() => _FocusListenerExampleState();
}

class _FocusListenerExampleState extends State<FocusListenerExample> {
  late FocusNode _focusNode;
  String _status = '未获取焦点';

  
  void initState() {
    super.initState();
    _focusNode = FocusNode();
    _focusNode.addListener(() {
      setState(() {
        _status = _focusNode.hasFocus ? '已获取焦点' : '未获取焦点';
      });
    });
  }

  
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          focusNode: _focusNode,
          decoration: const InputDecoration(hintText: '输入文本'),
        ),
        Text('状态: $_status'),
      ],
    );
  }
}

代码解释: FocusNode 的 addListener 监听焦点变化。hasFocus 属性表示是否获得焦点。这在需要根据焦点状态改变 UI 的场景中很有用。

示例 4:焦点作用域

class FocusScopeExample extends StatefulWidget {
  
  State<FocusScopeExample> createState() => _FocusScopeExampleState();
}

class _FocusScopeExampleState extends State<FocusScopeExample> {
  late FocusNode _focusNode1;
  late FocusNode _focusNode2;

  
  void initState() {
    super.initState();
    _focusNode1 = FocusNode();
    _focusNode2 = FocusNode();
  }

  
  void dispose() {
    _focusNode1.dispose();
    _focusNode2.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return FocusScope(
      onKey: (node, event) {
        return KeyEventResult.ignored;
      },
      child: Column(
        children: [
          TextField(
            focusNode: _focusNode1,
            decoration: const InputDecoration(hintText: '输入框1'),
          ),
          TextField(
            focusNode: _focusNode2,
            decoration: const InputDecoration(hintText: '输入框2'),
          ),
        ],
      ),
    );
  }
}

代码解释: FocusScope 定义焦点作用域,onKey 拦截键盘事件。这在需要自定义键盘行为的场景中很有用。

示例 5:键盘导航

class KeyboardNavigationExample extends StatefulWidget {
  
  State<KeyboardNavigationExample> createState() => _KeyboardNavigationExampleState();
}

class _KeyboardNavigationExampleState extends State<KeyboardNavigationExample> {
  late FocusNode _focusNode1;
  late FocusNode _focusNode2;
  late FocusNode _focusNode3;

  
  void initState() {
    super.initState();
    _focusNode1 = FocusNode();
    _focusNode2 = FocusNode();
    _focusNode3 = FocusNode();
  }

  
  void dispose() {
    _focusNode1.dispose();
    _focusNode2.dispose();
    _focusNode3.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          focusNode: _focusNode1,
          decoration: const InputDecoration(hintText: '输入框1'),
        ),
        TextField(
          focusNode: _focusNode2,
          decoration: const InputDecoration(hintText: '输入框2'),
        ),
        TextField(
          focusNode: _focusNode3,
          decoration: const InputDecoration(hintText: '输入框3'),
        ),
      ],
    );
  }
}

代码解释: 多个 FocusNode 支持 Tab 键在输入框间导航。这在表单中很常见,提升 PC 端用户体验。

高级话题

1. 动态/响应式设计

根据屏幕大小调整焦点。

2. 动画与过渡

自定义焦点动画。

3. 搜索/过滤/排序

焦点可以触发搜索。

4. 选择与批量操作

支持焦点选择。

5. 加载与缓存

显示加载状态。

6. 键盘导航

支持键盘快捷键。

7. 无障碍支持

提供无障碍支持。

8. 样式自定义

自定义样式。

9. 数据持久化/导出

保存状态。

10. 单元测试与集成测试

测试功能。

PC 端适配要点

  • 根据屏幕大小调整焦点
  • 支持键盘快捷键
  • 提供清晰的焦点指示

实际应用场景

  • 表单输入:管理表单焦点
  • 键盘导航:支持键盘导航
  • 无障碍:提供无障碍支持
  • 快捷键:支持快捷键

扩展建议

  • 学习高级焦点库
  • 研究性能优化
  • 探索自定义效果
  • 集成焦点库

总结

FocusNode 是管理焦点的有效方式。通过灵活使用 FocusNode,可以创建各种焦点管理效果。欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐