Saman
Saman

Reputation: 2656

onChange TextField move cursor to start in flutter

I try to check input with onChange method in TextField but after replacing text with TextEditingController cursor move to start of TextField.

This problem occurs only on the Android platform.

Code

TextField(
controller: textEditController,
onChanged: (content) {
                    textEditController.text = checkNumber(content);
                  },)

flutter version

[✓] Flutter (Channel master, v1.2.2-pre.41, on Mac OS X 10.14.3 18D109, locale
    en-IR)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)

Upvotes: 23

Views: 34599

Answers (4)

Carlos
Carlos

Reputation: 33

This worked for me (I store the textEditController in a variable):

TextField(
  controller: textEditController,
  onChanged: (content) {
     int cursorPos = textEditController.selection.base.offset;               
     textEditController.text = checkNumber(content);
     textEditController.selection = TextSelection.fromPosition(TextPosition(offset: cursorPos));
    },)

Upvotes: 1

vishwajit76
vishwajit76

Reputation: 2448

**If you want to move cursor dynamically with text **

setState(() {

    String text = "sometext";

    _controller.value = TextEditingValue(
             text: text,
             selection: TextSelection(
                       baseOffset: text.length,
                       extentOffset: text.length)
    );
});

Upvotes: 8

Nick
Nick

Reputation: 1215

The accepted solution didn't work for me - as I was setting both text and selection I needed to instead set value.

The TextEditingController class documentation states:

The text or selection properties can be set from within a listener added to this controller. If both properties need to be changed then the controller's value should be set instead.

The documentation also has a relevant example that includes the following:

void initState() {
  _controller.addListener(() {
    final text = _controller.text.toLowerCase();
    _controller.value = _controller.value.copyWith(
      text: text,
      selection: TextSelection(baseOffset: text.length, extentOffset: text.length),
      composing: TextRange.empty,
    );
  });
  super.initState();
}

This forces the entered text to be lower case and keeps the cursor at the end of the input.

Upvotes: 14

Günter Zöchbauer
Günter Zöchbauer

Reputation: 657068

Set the selection using the TextEditingController

TextField(
controller: textEditController,
onChanged: (content) {
  textEditController..text = checkNumber(content)
                    ..selection = TextSelection.collapsed(offset: 0);
  },
)

Upvotes: 31

Related Questions