diff --git a/packages/zefyr/lib/src/widgets/editable_text.dart b/packages/zefyr/lib/src/widgets/editable_text.dart index ff44cfcc6..c37cf4b8a 100644 --- a/packages/zefyr/lib/src/widgets/editable_text.dart +++ b/packages/zefyr/lib/src/widgets/editable_text.dart @@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter/rendering.dart'; import 'package:notus/notus.dart'; import 'code.dart'; @@ -172,6 +173,7 @@ class _ZefyrEditableTextState extends State super.initState(); _focusAttachment = _focusNode.attach(context); _input = InputConnectionController(_handleRemoteValueChange); + _scrollController.addListener(_handleScrollChange); _updateSubscriptions(); } @@ -223,6 +225,7 @@ class _ZefyrEditableTextState extends State // final ScrollController _scrollController = ScrollController(); + double _scrollOffset = 0.0; ZefyrRenderContext _renderContext; CursorTimer _cursorTimer; InputConnectionController _input; @@ -284,6 +287,7 @@ class _ZefyrEditableTextState extends State _renderContext.removeListener(_handleRenderContextChange); widget.controller.removeListener(_handleLocalValueChange); _focusNode.removeListener(_handleFocusChange); + _scrollController.removeListener(_handleScrollChange); _input.closeConnection(); _cursorTimer.stop(); } @@ -320,4 +324,17 @@ class _ZefyrEditableTextState extends State // nothing to update internally. }); } + + void _handleScrollChange() { + ScrollDirection scrollDirection = _scrollController.position.userScrollDirection; + if (scrollDirection == ScrollDirection.idle && widget.controller.selection.isCollapsed) { + if (widget.controller.document.length - 1 == widget.controller.selection.end) { + _scrollController.jumpTo(_scrollController.position.maxScrollExtent); + } else { + _scrollController.jumpTo(_scrollOffset); + } + } else { + _scrollOffset = _scrollController.offset; + } + } }