简体   繁体   English

颤动中的标签顺序

[英]Tab order in flutter

On my Windows App ( The interface looks like this: https://i.stack.imgur.com/SibAC.png )在我的 Windows 应用程序上(界面如下所示: https ://i.stack.imgur.com/SibAC.png)

When I focused to Input-1, and I press Tab key on keyboard, the primary focus will focus to Input-3.当我聚焦到 Input-1 并按下键盘上的 Tab 键时,主要焦点将聚焦到 Input-3。 Is there any way to re-arrange my focus order: Input-1 -> Input-2 -> Input-3 -> Input-4 -> Input-5.有什么方法可以重新排列我的焦点顺序:Input-1 -> Input-2 -> Input-3 -> Input-4 -> Input-5。

Attention: This is not Tab bar/tab controller in flutter's docs example.注意:这不是颤振文档示例中的选项卡栏/选项卡控制器。

This is my code:这是我的代码:

3 files is in same root 3个文件在同一个根目录

main.dart

import 'package:flutter/material.dart';
import 'tab1.dart';
import 'tab2.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Tab oder',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Tab order'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final TextEditingController _controller = TextEditingController();
  final FocusNode _focusNode = FocusNode();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Form(
        key: GlobalKey<FormState>(),
        onChanged: () {
          Form.of(primaryFocus!.context!)!.save();
        },
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Container(
              constraints: const BoxConstraints.tightFor(width: 200.0, height: 200.0),
              child: TextFormField(
                controller: _controller,
                focusNode: _focusNode,
                decoration: const InputDecoration(
                  filled: true,
                  fillColor: Colors.yellow,
                ),
              ),
            ),
            const SizedBox(width: 150.0),
            Column(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                Container(
                  constraints: const BoxConstraints.tightFor(width: 200.0, height: 120.0),
                  child: Tab1(),
                ),
                Container(
                  constraints: const BoxConstraints.tightFor(width: 200.0, height: 120.0),
                  child: Tab2(),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

tab1.dart

import 'package:flutter/material.dart';

class Tab1 extends StatefulWidget {
  @override
  _Tab1State createState() => _Tab1State();
}

class _Tab1State extends State<Tab1> {
  final TextEditingController _controller1 = TextEditingController();
  final TextEditingController _controller2 = TextEditingController();
  final FocusNode _focusNode1 = FocusNode();
  final FocusNode _focusNode2 = FocusNode();

  @override
  build(BuildContext context) {
    return Column(
      children: [
        TextFormField(
          controller: _controller1,
          focusNode: _focusNode1,
          decoration: const InputDecoration(
            filled: true,
            fillColor: Colors.greenAccent,
          ),
        ),
        TextFormField(
          controller: _controller2,
          focusNode: _focusNode2,
          decoration: const InputDecoration(
            filled: true,
            fillColor: Colors.greenAccent,
          ),
        ),
      ],
    );
  }
}

tab2.dart

import 'package:flutter/material.dart';

class Tab2 extends StatefulWidget {
  @override
  _Tab2State createState() => _Tab2State();
}

class _Tab2State extends State<Tab2> {
  final TextEditingController _controller1 = TextEditingController();
  final TextEditingController _controller2 = TextEditingController();
  final FocusNode _focusNode1 = FocusNode();
  final FocusNode _focusNode2 = FocusNode();

  @override
  build(BuildContext context) {
    return Column(
      children: [
        TextFormField(
          controller: _controller1,
          focusNode: _focusNode1,
          decoration: const InputDecoration(
            filled: true,
            fillColor: Colors.greenAccent,
          ),
        ),
        TextFormField(
          controller: _controller2,
          focusNode: _focusNode2,
          decoration: const InputDecoration(
            filled: true,
            fillColor: Colors.greenAccent,
          ),
        ),
      ],
    );
  }
}

You can achieve the behavior you want via a FocusTraversalGroup , with this widget you specify the order in which you want the traversal to be performed.您可以通过FocusTraversalGroup实现您想要的行为,使用此小部件可以指定您希望执行遍历的顺序。

This widgets takes a traversal policy as a parameter, I used a OrderedTraversalPolicy , but there are others like:这个小部件将遍历策略作为参数,我使用了OrderedTraversalPolicy ,但还有其他类似的:

WidgetOrderTraversalPolicy , a policy that relies on the widget creation order to describe the order of traversal. WidgetOrderTraversalPolicy ,一种依赖于小部件创建顺序来描述遍历顺序的策略。

ReadingOrderTraversalPolicy , a policy that describes the order as the natural "reading order" for the current Directionality. ReadingOrderTraversalPolicy ,一种将顺序描述为当前方向性的自然“阅读顺序”的策略。

NumericFocusOrder, a focus order that assigns a numeric traversal order. NumericFocusOrder,分配数字遍历顺序的焦点顺序。

LexicalFocusOrder a focus order that assigns a string-based lexical traversal order. LexicalFocusOrder分配基于字符串的词法遍历顺序的焦点顺序。

Also there is an really interesting section about building adaptive apps in which focus and traversal order in different platforms is part of, you can check it out here还有一个关于构建自适应应用程序的非常有趣的部分,其中不同平台中的焦点和遍历顺序是其中的一部分,你可以在这里查看

class Tab1 extends StatefulWidget {
  @override
  _Tab1State createState() => _Tab1State();
}

class _Tab1State extends State<Tab1> {
  final TextEditingController _controller1 = TextEditingController();
  final TextEditingController _controller2 = TextEditingController();
  final FocusNode _focusNode1 = FocusNode();
  final FocusNode _focusNode2 = FocusNode();

  @override
  build(BuildContext context) {
    return FocusTraversalGroup(
      policy: OrderedTraversalPolicy(),

If you need to change the traversal order of other groups(like tab2) simply wrap them in another FocusTraversalGroup and specify the policy you want them to follow.如果您需要更改其他组(如 tab2)的遍历顺序,只需将它们包装在另一个FocusTraversalGroup中并指定您希望它们遵循的策略。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM