Flutter Web - 文本字段滚动而不是选择长文本

Posted

技术标签:

【中文标题】Flutter Web - 文本字段滚动而不是选择长文本【英文标题】:Flutter Web - Text field scrolls instead of selecting for long text 【发布时间】:2021-04-08 03:05:03 【问题描述】:

我遇到了 Flutter Web 的 TextField 的问题。每当文本变得太长,从而导致 TextField 滚动以查看所有内容(在单行字段中)时,我不再能够单击并拖动以选择文本。当文本较短时,选择很好。您可以通过此处附加的 GIF 看到这一点:

我认为这与手势捕获顺序错误有关,但我一直无法找到解决方法。

根据this github issue 上的一些人的说法,文本选择问题的一种解决方案是使用以下两个命令之一:

    flutter run -d chrome --release --dart-define=FLUTTER_WEB_USE_SKIA=true flutter run -d chrome --release --dart-define=FLUTTER_WEB_USE_EXPERIMENTAL_CANVAS_TEXT=true

虽然问题在于多行文本字段,但不幸的是,这似乎都无法解决我的问题。

我尝试使用多行文本框,但如果我将 maxLines 设置为 5 之类的固定数字,我会在垂直滚动和选择方面遇到类似问题。

我曾考虑使用诸如flutter_html 之类的html 渲染插件来以这种方式渲染文本字段,但如果可能的话,我想避免这样做。

【问题讨论】:

见github.com/flutter/flutter/issues/59141 【参考方案1】:

我遇到了同样的问题并找到了这个解决方案:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

class TextFieldScrollTest extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    final scrollController = ScrollController();
    final textController = TextEditingController(text: '________a________b_________c________d________e_______f_______g_______h______i_______j_________k__________l__________m________n_________o_______p');
    return Scaffold(
      body: Listener(
        onPointerSignal: (_) 
          if (_ is PointerScrollEvent) 
            _scrollController.jumpTo(
              math.max(
                math.min(
                  _scrollController.position.maxScrollExtent,
                  _scrollController.offset + _.scrollDelta.dx,
                ),
                _scrollController.position.minScrollExtent,
              ),
            );
          
        ,
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 500),
          child: TextField(
            controller: textController,
            scrollPhysics: const NeverScrollableScrollPhysics(),
            scrollController: scrollController,
          ),
        ),
      ),
    );
  

可以使用NeverScrollableScrollPhysics 抑制您遇到的行为(鼠标拖动文本滚动文本而不是选择)。但是,这将阻止所有滚动。 ListeneronPointerSignal 将使用鼠标滚轮或触摸板的两指滑动来检测水平滚动。

【讨论】:

奇怪的是,我也在点击和拖动滚动,这是更重要的停止,因为这意味着我无法选择文本框中的文本。这也解决了这个问题吗? 您尝试过我发布的小部件吗?您可以将此代码粘贴到一个新文件中,并在您的应用程序中的某处使用TextFieldScrollTest(),导入文件并检查。在此小部件内单击并拖动应该选择文本,而不是滚动。 抱歉,当时无法对此进行实际操作。我刚刚尝试过,它适用于选择已经滚动到视图中的文本,以及使用笔记本电脑上的触摸板滚动。但是,我无法使用鼠标滚轮滚动。虽然我怀疑这可以通过检测它是否是滚轮,或者是否按下 shift 并使用 y 偏移来解决。我还注意到,如果您尝试在边缘选择文本,它不会将选择滚动到视图中。关于如何解决这个问题的任何想法? 这个答案不允许用光标滚动,只能用指针滚动。

以上是关于Flutter Web - 文本字段滚动而不是选择长文本的主要内容,如果未能解决你的问题,请参考以下文章

输入文本时自动扩展的 Flutter 文本字段,然后在达到特定高度时开始滚动文本

Flutter :启用文本字段时,背景图像向上移动。 “resizeToAvoidBottomInset”禁用滚动。我哪里错了?

多对多字段的 Django 表单上的逗号分隔文本而不是多项选择

Flutter - 文本字段标签溢出切断文本

Flutter 中的文本字段验证

滚动表格视图时隐藏文本字段数据