首页 > 解决方案 > Flutter - FocusNodes 和 Navigator 导致 TextField 失去装饰

问题描述

我遇到了一个非常奇怪的 Flutter bug,也许有人对此有所了解。

Flutter 目前还没有一种很好的方法来自动从表单中的 TextField 移动到 Textfield。推荐的解决方案是为每个 Textfield 创建一个 FocusNode,然后当用户完成编辑时,以编程方式选择下一个 FocusNode。

似乎工作正常,但是如果您的表单不在应用程序的第一条路线上,它也会导致一些非常奇怪的视觉故障(通常情况并非如此)

在第二条路线上,当你点击一个 TextField 时,装饰会瞬间闪烁然后消失,但光标会保留。您可以继续选择 TextFields,最终您将在每个字段上都有一个光标。该字段仍然正常运行,所以这纯粹是一个视觉故障。

具有多个光标的 TextField

这个问题似乎与导航器密切相关。如果您使用自定义 FocusNodes 在第一条路线上创建一个屏幕,它的行为很好。相反,如果您不在第二个屏幕上使用 FocusNodes,它也可以。只有当您将这两者结合起来时,才会出现问题。

这是一个展示此问题的简单应用程序。

import 'package:flutter/material.dart';

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

class TestApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: TestScreen(),
    );
  }
}

class TestScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: RaisedButton(
            onPressed: () => _pushSecondScreen(context),
            child: Text('Push to a new screen')
          ),
        ),
      )
    );
  }

  void _pushSecondScreen(BuildContext context) {
    Navigator.of(context).push(MaterialPageRoute(builder: (_) =>     SecondTest()));
  }
}

class SecondTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Screen'),
      ),
      body: ListView(
        padding: EdgeInsets.all(20.0),
        children: List<Widget>.generate(10, (i) => _buildTextField(i)),
      ),
   );
 }

 Widget _buildTextField(int index) {
    // The custom focus node is thrown in here for example, but in a real world app,
    // a reference to the node would be kept so the app can manage focus between the nodes
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 8.0),
      child: TextField(
        focusNode: FocusNode(),
        decoration: InputDecoration(
          labelText: 'Field $index',
          filled: true,
          border: OutlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(5.0))
          )
        ),
      ),
    );
  }
}

我发布了代码以在此要点中复制此问题: https ://gist.github.com/bkayfitz-cara/8da2afd964c7f4417435e9df49b4cd9e

标签: flutter

解决方案


我在多个文本字段上使用 FocusNode 时也有类似的体验,每个字段上都有一个光标。然后我意识到我需要为每个文本字段实例化一个单独的 FocusNode,问题就消失了。


推荐阅读