MattChris
MattChris

Reputation: 457

Flutter Web - Text field scrolls instead of selecting for long text

I'm having an issue with Flutter Web's TextField. Whenever The text becomes too long, and thus causes the TextField to scroll over to view it all (in single line fields), I am no longer able to click-and-drag to select the text. When the text is shorter, the selection is fine. You can see that with the GIF attached here: visual of the problem

I assume it has something to do with the order of gesture capturing being wrong, but I haven't been able to find a way to fix it.

According to a few people on this github issue, one solution to problems with text selection is to use one of the two following commands:

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

Although the issue is for multi-line text fields, and unfortunately neither seems to solve my issue.

I've tried using a multi-line text box, though if I set maxLines to a fixed number like 5, I get a similar problem with vertical scrolling and selection.

I've thought about using an html rendering plugin such as flutter_html to just render a text field that way, but I'd like to avoid doing that if it's at all possible.

Upvotes: 7

Views: 1845

Answers (2)

Mina Hamdy
Mina Hamdy

Reputation: 1

I had the same issue, so I tried different scroll physics and FixedExtentScrollPhysics seems to fix it, I tested it on Web only so make sure to test on platforms you use first.

TextField(
   controller: textController,
   scrollPhysics: const FixedExtentScrollPhysics(),
),

Note: There's an assertion that fails regarding the parent having to use FixedExtentScrollController, I just ignored it as it's not causing an issue in my case.

Upvotes: 0

Marc Brun
Marc Brun

Reputation: 121

I had the same problem and found this solution:

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,
          ),
        ),
      ),
    );
  }
}

The behavior you are experiencing (mouse dragging on text scrolls the text instead of selecting) can be suppressed with the NeverScrollableScrollPhysics. This will however prevent all scrolling. The Listener's onPointerSignal will detect horizontal scrolling using mouse wheel or touchpad's two-fingers swipe.

Upvotes: 5

Related Questions