首页 > 解决方案 > 聚焦焦点小部件下方的第一个可聚焦元素

问题描述

我正在尝试将第一个可聚焦元素集中在小部件下方Focus。考虑以下人工示例。它包含一个BarWidgetwith some TextField

FooWidgetFocus定的focusNode. 一秒钟后,我想关注BarWidget. 请不要说我不想将 a FocusNodedown传递给BarWidget.

import 'package:flutter/material.dart';

void main() {
  runApp(Foo());
}

class Foo extends StatefulWidget {
  @override
  State createState() => FooState();
}

class FooState extends State<Foo> {
  final focusNode = FocusNode();

  void initState() {
    super.initState();
    Future.delayed(
      const Duration(seconds: 1),
      focusNode.requestFocus,
    );
  }

  @override
  Widget build(BuildContext context) => MaterialApp(
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: BarWidget(),
          ),
        ),
      );
}

class BarWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) => Column(
        children: [
          Text("Foo"),
          TextField(),
          Text("Bar"),
        ],
      );
}

标签: flutter

解决方案


理论上可以通过使用FocusTraversalPolicy.sortDescendants. 但是,该方法被声明为@protected. 见:https ://github.com/flutter/flutter/issues/70534

完整示例:

import 'package:flutter/material.dart';

void main() {
  runApp(Foo());
}

class Foo extends StatefulWidget {
  @override
  State createState() => FooState();
}

class FooState extends State<Foo> {
  final focusNode = FocusNode(canRequestFocus: false);

  void initState() {
    super.initState();
    void f() {
      final policy = FocusTraversalGroup.of(focusNode.context);
      // ignore: invalid_use_of_protected_member
      final node = policy.sortDescendants(focusNode.traversalDescendants, null).first;
      node.requestFocus();
    }
    Future.delayed(
      const Duration(seconds: 1),
      f,
    );
  }

  @override
  Widget build(BuildContext context) => MaterialApp(
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: BarWidget(),
          ),
        ),
      );
}

class BarWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) => Column(
        children: [
          Text("Foo"),
          TextField(),
          Text("Bar"),
        ],
      );
}

推荐阅读