Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Flutter readonly Textfield set caret to end

I have a TextField that I set to readonly, and it contains a TextEditingController. When I set the text on the controller through code, I want the text field to jump all the way to the back.

enter image description here

TextField(
  readOnly: true,
  controller: _dialogStore.exportFolderPathController,
),

The store in this case is part of mobx, which I use instead of stateful widgets. But that doesn’t matter for the question here.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I have a rather small text box. So when the text is long I want the text field to scroll all the way to the end. When I set the text on the scroll controller via exportFolderPathController.selection = TextSelection.collapsed(offset: exportFolderPathController.text.length);, it doesn’t want to update, but when I set readonly to false, it does work.

I have been digging through the code and found hints of if(readonly), for showing the selection handlers.

Eventually I got it to work with a dirty bool and a Future.delayed solution like so:

Future<void> setFilePath(String filePath) async {
  _readonly = false;
  exportFolderPathController.text = filePath;
  exportFolderPathController.selection =
      TextSelection.collapsed(offset: exportFolderPathController.text.length);
  // wait for the scroll animation to finish
  await Future.delayed(const Duration(milliseconds: 300));
  _readonly = true;
}

I really don’t like the Future.delayed here, since it’s an assumtion that it will take a while for the animation to finish. What are my alternatives?

I saw that there is also the possibility to add a ScrollController, but I couldn’t get that to work.

>Solution :

The quickest and easiest solution is below

Initialize a scrollController

final ScrollController _scrollController = ScrollController();

Then assign that controller in TextField

TextField(
  readOnly: true,
  controller: _dialogStore.exportFolderPathController,
  scrollController: _scrollController,
)

Last step is to add 2 lines in your setFilePath() method

Future<void> setFilePath(String filePath) async {
  WidgetsBinding.instance.addPostFrameCallback((_) {
    final scrollOffset = _scrollController.position.maxScrollExtent;
    _scrollController.jumpTo(scrollOffset);
  });
}

call above method in initState.

And you’re done. You’ll achieve what you want.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading