如何在 flutter 中将焦点转移和撤消焦点从一个小部件到另一个小部件?

问题描述 投票:0回答:1

我对 flutter 很陌生,我现在正在学习这个焦点是如何工作的?
到目前为止,从 ai chats 和 stackoverflow [链接][1] (我发现的最好的链接之一)我已经了解了“focusnode”,但我有一些查询需要解决方案。

只是关于这种方法是否可行的一些信息
我一直是 c# 和 vb.net winforms 的开发人员,几乎每个组件或小部件都有一个很好的

TabIndex
选项,在这种情况下,我们只需要编写数字,系统会自动处理选项卡(重点是下一个)/shift+tabs(焦点到上一个)。
我知道 flutter 是为了实现跨设备(如果我没记错的话,主要是针对移动设备),但我发现这种方法没有任何地方,并且在进一步搜索中我发现这在 flutter 中不可用。我的意思是即使 HTML 也有这个 TabIndex 功能。

我还看到 AI 生成了有关使用

focusnode
并为每个文本字段声明每个
focusnode
的代码。我发现这种方法很有用,但如果我在单个表单/页面/窗口中有大约 25 个文本字段,那会不会很乏味?

我还发现了这行代码

FocusScope.of(context).nextFocus()
但是我如何让flutter知道我想从第一个文本字段集中到第三个文本字段而不是第二个文本字段。
另外,如果我使用shift + tab,我怎样才能获得上一个焦点选项卡的焦点?

最后一个小总结,
想要的是

  1. 如何在 Enter/Return 或 Tab 按键上聚焦到特定文本字段或按钮?
  2. 如何在 Shift + Tab 按键上将焦点转移到上一个文本字段或按钮?

注意,我不知道为什么我不能附加上面的链接,但这是链接:如何将焦点转移到 Flutter 中的下一个 TextField?

希望版主能编辑一下。

flutter dart button focus textfield
1个回答
0
投票

您可以通过将字段、按钮等包装在

FocusTraversalGroup
中并提供
FocusTraversalPolicy
来操纵字段、按钮等的聚焦顺序。

FocusTraversalGroup(
  policy: policy, // your FocusTraversalPolicy here
  child: ..., // the objects you want to focus go in the child subtree
),

您可以选择几种不同的政策:

如果您想为每个可聚焦项目提供特定的数字顺序,那么您需要

OrderedTraversalPolicy
。根据此策略,您还必须使用
FocusTraversalOrder
小部件包装您想要关注的每个项目。

FocusTraversalOrder(
  order: NumericFocusOrder(order), // the focus order it should appear in the group
  child: ..., // button or field you want to focus
),

我整理了一个小演示,您可以用它来尝试不同的焦点策略。

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    title: 'Focus Demo',
    home: FocusPage(),
  ));
}

class FocusPage extends StatefulWidget {
  const FocusPage({super.key});

  @override
  State<FocusPage> createState() => _FocusPageState();
}

FocusTraversalPolicy orderedTraversalPolicy = OrderedTraversalPolicy();
FocusTraversalPolicy readingTraversalPolicy = ReadingOrderTraversalPolicy();
FocusTraversalPolicy widgetTraversalPolicy = WidgetOrderTraversalPolicy();

class _FocusPageState extends State<FocusPage> {
  List<List<({String name, double order})>> fields = [
    [
      (name: 'A', order: 4),
      (name: 'B', order: 2),
      (name: 'C', order: 6),
    ],
    [
      (name: 'D', order: 3),
      (name: 'E', order: 5),
      (name: 'F', order: 1),
    ],
  ];

  FocusTraversalPolicy? policy = orderedTraversalPolicy;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Focus Demo'),
        actions: [
          FocusTraversalGroup(
            descendantsAreTraversable: false,
            child: DropdownButton<FocusTraversalPolicy>(
              value: policy,
              items: [
                DropdownMenuItem(
                  value: orderedTraversalPolicy,
                  child: const Text('Custom Order'),
                ),
                DropdownMenuItem(
                  value: readingTraversalPolicy,
                  child: const Text('Reading Order'),
                ),
                DropdownMenuItem(
                  value: widgetTraversalPolicy,
                  child: const Text('Widget Order'),
                ),
              ],
              onChanged: (v) {
                setState(() {
                  policy = v;
                });
              },
            ),
          ),
        ],
      ),
      body: FocusTraversalGroup(
        policy: policy,
        child: Row(
          children: [
            for (var row in fields)
              Expanded(
                child: Column(
                  children: [
                    for (var (:name, :order) in row)
                      Expanded(
                        child: Padding(
                          padding: const EdgeInsets.all(25),
                          child: FocusTraversalOrder(
                            order: NumericFocusOrder(order),
                            child: TextField(
                              decoration: InputDecoration(
                                labelText: name,
                              ),
                            ),
                          ),
                        ),
                      ),
                  ],
                ),
              ),
          ],
        ),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.