From dd89ae96c4aefa51837e3a8ea648d30db9e1dc5b Mon Sep 17 00:00:00 2001 From: zhengzeqin Date: Tue, 24 Jun 2025 16:04:12 +0800 Subject: [PATCH] When maintainHintSize is false, hint is centered and aligned, it is different from the original one (#168654) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR changes the Hint uses topLeft alignment when maintainHintSize is false > code ```dart buildTextField() { return const Center( child: TextField( decoration: InputDecoration( hintText: 'hint', maintainHintSize: false, ), ), ); } ``` Before: b After: a ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. --------- Co-authored-by: 郑泽钦 --- .../lib/src/material/input_decorator.dart | 5 +++ .../test/material/input_decorator_test.dart | 39 +++++++++++++++++++ 2 files changed, 44 insertions(+) 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', () {