【问题标题】:TextField focus stuck when dropdown button is selected选择下拉按钮时,TextField 焦点卡住
【发布时间】:2020-02-19 03:40:45
【问题描述】:

我有一个文本字段和一个下拉菜单,它们都由 Bloc 控制。我遇到的问题是,一旦选择了文本字段,如果用户随后尝试从下拉菜单中选择某些内容,它就不会放弃焦点。菜单出现,然后立即消失,焦点仍然在文本字段上。

这是一个演示问题的基本应用程序:

import 'dart:async';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Textfield Focus Example',
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {

  FormBloc formBloc = FormBloc();

  final List<DropdownMenuItem> userMenuItems = ['Bob', 'Frank']
      .map((String name) => DropdownMenuItem(
            value: name,
            child: Text(name),
          ))
      .toList();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            // user - drop down menu
            Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text('To: '),
                StreamBuilder<String>(
                    stream: formBloc.selectedUser,
                    builder: (context, snapshot) {
                      return DropdownButton(
                          items: userMenuItems,
                          value: snapshot.data,
                          onChanged: formBloc.selectUser);
                    }),
              ],
            ),

            // amount - text field
            Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text('Amount: '),
                Container(
                    width: 100.0,
                    child: StreamBuilder<double>(
                        stream: formBloc.billAmount,
                        builder: (context, snapshot) {
                          return TextField(
                            keyboardType: TextInputType.number,
                            onChanged: formBloc.newBillAmount,
                          );
                        })),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class FormBloc {
  StreamController<String> _selectedUserController = StreamController<String>();
  Stream<String> get selectedUser =>
      _selectedUserController.stream;
  Function get selectUser => _selectedUserController.sink.add;

  //Amount
  StreamController<double> _billAmountController = StreamController<double>();
  Stream<double> get billAmount =>
      _billAmountController.stream;
  void newBillAmount(String amt) =>
      _billAmountController.sink.add(double.parse(amt));


  void dispose() {
    _selectedUserController.close();
    _billAmountController.close();
  }
}

我是否需要手动为 textField 声明 FocusNode 并告诉它何时放弃焦点?还是有其他原因导致文本字段占据了所有注意力?

【问题讨论】:

    标签: flutter dart bloc


    【解决方案1】:

    将这行代码添加到您的 TextField:focusNode: FocusNode(canRequestFocus: false)

    这应该可以防止您的TextField 在单击下拉列表后请求焦点。

    代码:

    // amount - text field
    Row(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
        Text('Amount: '),
        Container(
            width: 100.0,
            child: StreamBuilder<double>(
                stream: formBloc.billAmount,
                builder: (context, snapshot) {
                    return TextField(
                    focusNode: FocusNode(canRequestFocus: false)
                    keyboardType: TextInputType.number,
                    onChanged: formBloc.newBillAmount,
                    );
                })),
        ],
    )
    

    【讨论】:

    • 您也可以尝试在 TextField 中使用 autofocus: false。
    【解决方案2】:

    抱歉,您需要在 DropDownButton Widget 的 onTapListener 中添加以下代码。当您在下拉菜单中选择或点击屏幕外时,它将移除对文本字段的关注。谢谢

    FocusScope.of(context).requestFocus(new FocusNode());
    

    【讨论】:

      【解决方案3】:

      此问题已解决并合并到flutter主频道
      https://github.com/flutter/flutter/pull/42482

      这解决了我们目前无法在 同一页面,因为当下拉菜单获得焦点时键盘消失会导致指标更改,并且下拉菜单在激活时会立即消失。

      【讨论】:

        【解决方案4】:

        上面的答案只有在你不想调用 requestFocus() 方法的情况下才是正确的。但在我的情况下,它是一个聊天应用程序,我希望文本字段在消息被滑动时获得焦点。如果设置布尔参数canRequestFocus,则为false。那我就不行了。

        在 chatPage 应用栏中,我使用了一个弹出菜单,这导致了同样的问题(无意中集中注意力。)

        所以,对我有用的是,在 popupmenu 的 onSelected(String str) 方法的最顶部,我调用了这个语句:

        messageFocusNode.nextFocus(); //messageFocusNode is the focusNode of the TextField.
        

        虽然我不知道为什么以及如何,但这对我有用。我是新手,如果您知道原因,请更新我的答案。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-04-30
          • 2021-06-23
          • 2011-05-11
          • 2011-06-13
          • 2016-12-07
          • 2021-02-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多