diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart index fd2a1bd0dc1..482342017b8 100644 --- a/packages/flutter/lib/src/material/input_decorator.dart +++ b/packages/flutter/lib/src/material/input_decorator.dart @@ -2267,6 +2267,10 @@ class _InputDecoratorState extends State with TickerProviderStat return FadeTransition(opacity: _curvedAnimation!, child: child); } + static Widget _topStartLayout(Widget? currentChild, List previousChildren) { + return Stack(children: [...previousChildren, if (currentChild != null) currentChild]); + } + @override Widget build(BuildContext context) { final ThemeData themeData = Theme.of(context); @@ -2308,6 +2312,7 @@ class _InputDecoratorState extends State with TickerProviderStat : AnimatedSwitcher( duration: decoration.hintFadeDuration ?? _kHintFadeTransitionDuration, transitionBuilder: _buildTransition, + layoutBuilder: _topStartLayout, child: showHint ? hintWidget : const SizedBox.shrink(), ); } diff --git a/packages/flutter/test/material/input_decorator_test.dart b/packages/flutter/test/material/input_decorator_test.dart index 7f1a225b663..2348872be0b 100644 --- a/packages/flutter/test/material/input_decorator_test.dart +++ b/packages/flutter/test/material/input_decorator_test.dart @@ -5271,6 +5271,45 @@ void main() { // The hintText replaced with SizeBox. expect(find.text(hintText), findsNothing); }); + + testWidgets('Hint does not change position when maintainHintSize is false - LTR', ( + WidgetTester tester, + ) async { + await tester.pumpWidget( + buildInputDecorator(isEmpty: true, decoration: const InputDecoration(hintText: hintText)), + ); + final double expectedHintLeft = getHintRect(tester).left; + + await tester.pumpWidget( + buildInputDecorator( + isEmpty: true, + decoration: const InputDecoration(hintText: hintText, maintainHintSize: false), + ), + ); + expect(getHintRect(tester).left, expectedHintLeft); + }); + + testWidgets('Hint does not change position when maintainHintSize is false - RTL', ( + WidgetTester tester, + ) async { + await tester.pumpWidget( + buildInputDecorator( + isEmpty: true, + decoration: const InputDecoration(hintText: hintText), + textDirection: TextDirection.rtl, + ), + ); + final double expectedHintRight = getHintRect(tester).right; + + await tester.pumpWidget( + buildInputDecorator( + isEmpty: true, + decoration: const InputDecoration(hintText: hintText, maintainHintSize: false), + textDirection: TextDirection.rtl, + ), + ); + expect(getHintRect(tester).right, expectedHintRight); + }); }); group('Material3 - InputDecoration helper/counter/error', () {