merge: 合并 K97 iOS 评论键盘避让
This commit is contained in:
commit
76f347cc35
3 files changed
+222
-121
No files matched your search
@@ -33,3 +33,38 @@ Running Gradle task 'assembleDebug'... 24.8s
|
|||||||
|
|
||||||
解读:静态分析零告警,553 项全量测试通过,debug APK 构建成功;
|
解读:静态分析零告警,553 项全量测试通过,debug APK 构建成功;
|
||||||
`pubspec.lock` 已还原,无依赖变更,未安装或操作真机。
|
`pubspec.lock` 已还原,无依赖变更,未安装或操作真机。
|
||||||
|
|
||||||
|
## 2026-10-21 K97 修复 iOS 评论输入弹窗键盘避让
|
||||||
|
|
||||||
|
- 已完整读取 K97 `docs/plans/INBOX.md`。
|
||||||
|
- 已从最新 `origin/develop` 创建 `fix/k97-ios-comment-keyboard`。
|
||||||
|
- 计划见 FruitServer `docs/plans/2026-10-21-K97-ios-comment-keyboard.md`。
|
||||||
|
- Android 保留既有 pinned/channel 策略;iOS 与其他平台改用实时
|
||||||
|
`MediaQuery.viewInsets.bottom`,并补 iOS 键盘避让测试。
|
||||||
|
- 已完成 `_isAndroid` 平台分流;Android 的 channel、80ms 防抖和 pinned 逻辑保持不变,
|
||||||
|
iOS/其他平台直接读取实时 viewInsets,超过屏幕 60% 的异常值按 0 处理。
|
||||||
|
- 面板已使用 160ms `easeOutCubic` AnimatedPadding;Android 不包裹 SafeArea,
|
||||||
|
iOS/其他平台使用 `SafeArea(top: false)` 处理 home indicator。
|
||||||
|
- 已补 iOS insets=300/0 测试,发表按钮在键盘上方;Android pinned 既有用例全部通过。
|
||||||
|
|
||||||
|
门禁原始输出:
|
||||||
|
|
||||||
|
```text
|
||||||
|
$ dart analyze lib test
|
||||||
|
Analyzing lib, test...
|
||||||
|
No issues found!
|
||||||
|
|
||||||
|
$ flutter test --no-pub
|
||||||
|
00:54 +555: All tests passed!
|
||||||
|
|
||||||
|
$ flutter build apk --debug
|
||||||
|
Running Gradle task 'assembleDebug'... 26.2s
|
||||||
|
✓ Built build/app/outputs/flutter-apk/app-debug.apk
|
||||||
|
|
||||||
|
$ flutter build ios --simulator --no-codesign
|
||||||
|
Xcode build done. 44.0s
|
||||||
|
✓ Built build/ios/iphonesimulator/Runner.app
|
||||||
|
```
|
||||||
|
|
||||||
|
解读:静态分析零告警,555 项全量测试通过,Android 与 iOS simulator 构建成功;
|
||||||
|
`pubspec.lock` 已还原,无依赖变更,未安装或操作真机。
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@@ -54,6 +55,9 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
|||||||
bool _useChannelInset = false;
|
bool _useChannelInset = false;
|
||||||
bool _keyboardVisible = false;
|
bool _keyboardVisible = false;
|
||||||
|
|
||||||
|
bool get _isAndroid =>
|
||||||
|
!kIsWeb && defaultTargetPlatform == TargetPlatform.android;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -66,6 +70,7 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
|||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
|
if (!_isAndroid) return;
|
||||||
if (!_pinnedInitialized) {
|
if (!_pinnedInitialized) {
|
||||||
_pinnedInitialized = true;
|
_pinnedInitialized = true;
|
||||||
_pinnedKeyboardInset =
|
_pinnedKeyboardInset =
|
||||||
@@ -75,10 +80,12 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _prepareInput() async {
|
Future<void> _prepareInput() async {
|
||||||
await _keyboardInset.start();
|
if (_isAndroid) {
|
||||||
if (!mounted) return;
|
await _keyboardInset.start();
|
||||||
_insetBaseline = _keyboardInset.value;
|
if (!mounted) return;
|
||||||
_insetReady = true;
|
_insetBaseline = _keyboardInset.value;
|
||||||
|
_insetReady = true;
|
||||||
|
}
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
_inputFocus.requestFocus();
|
_inputFocus.requestFocus();
|
||||||
@@ -112,7 +119,7 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _onKeyboardInsetChanged() {
|
void _onKeyboardInsetChanged() {
|
||||||
if (!mounted || !_insetReady) return;
|
if (!_isAndroid || !mounted || !_insetReady) return;
|
||||||
if (_keyboardInset.value != _insetBaseline) {
|
if (_keyboardInset.value != _insetBaseline) {
|
||||||
_useChannelInset = true;
|
_useChannelInset = true;
|
||||||
}
|
}
|
||||||
@@ -121,6 +128,9 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
|||||||
|
|
||||||
double _keyboardHeight(BuildContext context) {
|
double _keyboardHeight(BuildContext context) {
|
||||||
final viewInset = MediaQuery.viewInsetsOf(context).bottom;
|
final viewInset = MediaQuery.viewInsetsOf(context).bottom;
|
||||||
|
if (!_isAndroid) {
|
||||||
|
return _normalizeKeyboardInset(viewInset) ?? 0;
|
||||||
|
}
|
||||||
final channelInset = _useChannelInset
|
final channelInset = _useChannelInset
|
||||||
? _keyboardInset.value / MediaQuery.devicePixelRatioOf(context)
|
? _keyboardInset.value / MediaQuery.devicePixelRatioOf(context)
|
||||||
: 0.0;
|
: 0.0;
|
||||||
@@ -134,6 +144,7 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _trackKeyboardInset(double inset) {
|
void _trackKeyboardInset(double inset) {
|
||||||
|
if (!_isAndroid) return;
|
||||||
final visible = inset > 0;
|
final visible = inset > 0;
|
||||||
if (visible == _keyboardVisible) return;
|
if (visible == _keyboardVisible) return;
|
||||||
_keyboardVisible = visible;
|
_keyboardVisible = visible;
|
||||||
@@ -147,6 +158,7 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _captureSettledKeyboardInset() {
|
void _captureSettledKeyboardInset() {
|
||||||
|
if (!_isAndroid) return;
|
||||||
_keyboardSettleTimer = null;
|
_keyboardSettleTimer = null;
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
final inset = _keyboardHeight(context);
|
final inset = _keyboardHeight(context);
|
||||||
@@ -193,6 +205,109 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
|||||||
final hasContent = _input.text.trim().isNotEmpty;
|
final hasContent = _input.text.trim().isNotEmpty;
|
||||||
final canPost = signedIn && hasContent && !widget.controller.submitting;
|
final canPost = signedIn && hasContent && !widget.controller.submitting;
|
||||||
final multiline = _input.text.contains('\n');
|
final multiline = _input.text.contains('\n');
|
||||||
|
final bottomInset = _isAndroid
|
||||||
|
? _pinnedKeyboardInset
|
||||||
|
: _normalizeKeyboardInset(MediaQuery.viewInsetsOf(context).bottom) ?? 0;
|
||||||
|
|
||||||
|
final content = Padding(
|
||||||
|
key: const Key('comment-composer-sheet'),
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 12, 16, 12),
|
||||||
|
child: TextFieldTapRegion(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
if (widget.replyTo != null)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 8),
|
||||||
|
child: Text(
|
||||||
|
l10n.replyingTo(
|
||||||
|
widget.replyTo!.nickname.isEmpty
|
||||||
|
? l10n.anonymousUser
|
||||||
|
: widget.replyTo!.nickname,
|
||||||
|
),
|
||||||
|
style: const TextStyle(color: AppColors.muted, fontSize: 12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.commentInput,
|
||||||
|
borderRadius: BorderRadius.circular(_inputRadius),
|
||||||
|
),
|
||||||
|
child: TextField(
|
||||||
|
key: const Key('comment-composer-input'),
|
||||||
|
controller: _input,
|
||||||
|
focusNode: _inputFocus,
|
||||||
|
readOnly: !signedIn,
|
||||||
|
canRequestFocus: signedIn,
|
||||||
|
minLines: 1,
|
||||||
|
maxLines: 4,
|
||||||
|
maxLength: _maxCommentLength,
|
||||||
|
textAlignVertical: multiline
|
||||||
|
? TextAlignVertical.top
|
||||||
|
: TextAlignVertical.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.cream,
|
||||||
|
fontSize: 15,
|
||||||
|
height: multiline ? 1.4 : null,
|
||||||
|
),
|
||||||
|
cursorColor: AppColors.blue,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: signedIn
|
||||||
|
? l10n.writeComment
|
||||||
|
: l10n.commentLoginHint,
|
||||||
|
hintStyle: const TextStyle(
|
||||||
|
color: AppColors.muted,
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
|
counterText: '',
|
||||||
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16,
|
||||||
|
vertical: 12,
|
||||||
|
),
|
||||||
|
border: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
),
|
||||||
|
onTap: signedIn ? null : _authenticate,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: SizedBox(
|
||||||
|
height: _postButtonHeight,
|
||||||
|
child: TextButton(
|
||||||
|
key: const Key('comment-composer-post'),
|
||||||
|
onPressed: canPost ? _submit : null,
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
minimumSize: const Size(0, _postButtonHeight),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
backgroundColor: hasContent
|
||||||
|
? AppColors.blue.withValues(alpha: 0.12)
|
||||||
|
: AppColors.raised,
|
||||||
|
foregroundColor: AppColors.blue,
|
||||||
|
disabledForegroundColor: AppColors.muted,
|
||||||
|
disabledBackgroundColor: AppColors.raised,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
l10n.postComment,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return FocusScope(
|
return FocusScope(
|
||||||
key: const Key('comment-composer-focus-scope'),
|
key: const Key('comment-composer-focus-scope'),
|
||||||
@@ -222,122 +337,14 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
|||||||
borderRadius: const BorderRadius.vertical(
|
borderRadius: const BorderRadius.vertical(
|
||||||
top: Radius.circular(_sheetRadius),
|
top: Radius.circular(_sheetRadius),
|
||||||
),
|
),
|
||||||
child: SafeArea(
|
child: AnimatedPadding(
|
||||||
top: false,
|
key: const Key('comment-composer-keyboard-padding'),
|
||||||
bottom: false,
|
duration: const Duration(milliseconds: 160),
|
||||||
child: Padding(
|
curve: Curves.easeOutCubic,
|
||||||
padding: EdgeInsets.only(bottom: _pinnedKeyboardInset),
|
padding: EdgeInsets.only(bottom: bottomInset),
|
||||||
child: Padding(
|
child: _isAndroid
|
||||||
key: const Key('comment-composer-sheet'),
|
? content
|
||||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 12),
|
: SafeArea(top: false, child: content),
|
||||||
child: TextFieldTapRegion(
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
if (widget.replyTo != null)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 8),
|
|
||||||
child: Text(
|
|
||||||
l10n.replyingTo(
|
|
||||||
widget.replyTo!.nickname.isEmpty
|
|
||||||
? l10n.anonymousUser
|
|
||||||
: widget.replyTo!.nickname,
|
|
||||||
),
|
|
||||||
style: const TextStyle(
|
|
||||||
color: AppColors.muted,
|
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColors.commentInput,
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
_inputRadius,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: TextField(
|
|
||||||
key: const Key('comment-composer-input'),
|
|
||||||
controller: _input,
|
|
||||||
focusNode: _inputFocus,
|
|
||||||
readOnly: !signedIn,
|
|
||||||
canRequestFocus: signedIn,
|
|
||||||
minLines: 1,
|
|
||||||
maxLines: 4,
|
|
||||||
maxLength: _maxCommentLength,
|
|
||||||
textAlignVertical: multiline
|
|
||||||
? TextAlignVertical.top
|
|
||||||
: TextAlignVertical.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.cream,
|
|
||||||
fontSize: 15,
|
|
||||||
height: multiline ? 1.4 : null,
|
|
||||||
),
|
|
||||||
cursorColor: AppColors.blue,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: signedIn
|
|
||||||
? l10n.writeComment
|
|
||||||
: l10n.commentLoginHint,
|
|
||||||
hintStyle: const TextStyle(
|
|
||||||
color: AppColors.muted,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
counterText: '',
|
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 16,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
border: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
),
|
|
||||||
onTap: signedIn ? null : _authenticate,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
child: SizedBox(
|
|
||||||
height: _postButtonHeight,
|
|
||||||
child: TextButton(
|
|
||||||
key: const Key('comment-composer-post'),
|
|
||||||
onPressed: canPost ? _submit : null,
|
|
||||||
style: TextButton.styleFrom(
|
|
||||||
minimumSize: const Size(
|
|
||||||
0,
|
|
||||||
_postButtonHeight,
|
|
||||||
),
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 16,
|
|
||||||
),
|
|
||||||
tapTargetSize:
|
|
||||||
MaterialTapTargetSize.shrinkWrap,
|
|
||||||
backgroundColor: hasContent
|
|
||||||
? AppColors.blue.withValues(alpha: 0.12)
|
|
||||||
: AppColors.raised,
|
|
||||||
foregroundColor: AppColors.blue,
|
|
||||||
disabledForegroundColor: AppColors.muted,
|
|
||||||
disabledBackgroundColor: AppColors.raised,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
l10n.postComment,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -88,6 +88,53 @@ void main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('should_follow_live_view_insets_on_ios', (tester) async {
|
||||||
|
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
|
||||||
|
addTearDown(() => debugDefaultTargetPlatformOverride = null);
|
||||||
|
tester.view.physicalSize = const Size(390, 844);
|
||||||
|
tester.view.devicePixelRatio = 1;
|
||||||
|
addTearDown(tester.view.resetPhysicalSize);
|
||||||
|
addTearDown(tester.view.resetDevicePixelRatio);
|
||||||
|
addTearDown(tester.view.resetViewInsets);
|
||||||
|
final repository = FakeCommentRepository(pages: [const CommentPage()]);
|
||||||
|
|
||||||
|
await _pumpSheet(tester, repository: repository);
|
||||||
|
await tester.tap(find.byKey(const Key('comment-input-placeholder')));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
tester.view.viewInsets = const FakeViewPadding(bottom: 300);
|
||||||
|
await tester.pump();
|
||||||
|
await tester.pump(const Duration(milliseconds: 160));
|
||||||
|
|
||||||
|
final animatedPadding = tester.widget<AnimatedPadding>(
|
||||||
|
find.byKey(const Key('comment-composer-keyboard-padding')),
|
||||||
|
);
|
||||||
|
expect((animatedPadding.padding as EdgeInsets).bottom, 300);
|
||||||
|
expect(
|
||||||
|
tester.getBottomLeft(find.byKey(const Key('comment-composer-post'))).dy,
|
||||||
|
lessThanOrEqualTo(844 - 300),
|
||||||
|
);
|
||||||
|
debugDefaultTargetPlatformOverride = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('should_use_zero_live_inset_when_ios_keyboard_is_hidden', (
|
||||||
|
tester,
|
||||||
|
) async {
|
||||||
|
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
|
||||||
|
addTearDown(() => debugDefaultTargetPlatformOverride = null);
|
||||||
|
final repository = FakeCommentRepository(pages: [const CommentPage()]);
|
||||||
|
|
||||||
|
await _pumpSheet(tester, repository: repository);
|
||||||
|
await tester.tap(find.byKey(const Key('comment-input-placeholder')));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final animatedPadding = tester.widget<AnimatedPadding>(
|
||||||
|
find.byKey(const Key('comment-composer-keyboard-padding')),
|
||||||
|
);
|
||||||
|
expect((animatedPadding.padding as EdgeInsets).bottom, 0);
|
||||||
|
debugDefaultTargetPlatformOverride = null;
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('should_gate_guest_comment_input_without_focus', (tester) async {
|
testWidgets('should_gate_guest_comment_input_without_focus', (tester) async {
|
||||||
SharedPreferencesAsyncPlatform.instance =
|
SharedPreferencesAsyncPlatform.instance =
|
||||||
InMemorySharedPreferencesAsync.empty();
|
InMemorySharedPreferencesAsync.empty();
|
||||||
@@ -402,6 +449,8 @@ void main() {
|
|||||||
testWidgets('should_keep_comment_panel_fixed_and_open_composer_sheet', (
|
testWidgets('should_keep_comment_panel_fixed_and_open_composer_sheet', (
|
||||||
tester,
|
tester,
|
||||||
) async {
|
) async {
|
||||||
|
debugDefaultTargetPlatformOverride = TargetPlatform.android;
|
||||||
|
addTearDown(() => debugDefaultTargetPlatformOverride = null);
|
||||||
tester.view.physicalSize = const Size(390, 844);
|
tester.view.physicalSize = const Size(390, 844);
|
||||||
tester.view.devicePixelRatio = 1;
|
tester.view.devicePixelRatio = 1;
|
||||||
addTearDown(tester.view.resetPhysicalSize);
|
addTearDown(tester.view.resetPhysicalSize);
|
||||||
@@ -462,6 +511,7 @@ void main() {
|
|||||||
|
|
||||||
tester.view.viewInsets = const FakeViewPadding(bottom: 180);
|
tester.view.viewInsets = const FakeViewPadding(bottom: 180);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
await tester.pump(const Duration(milliseconds: 90));
|
||||||
await tester.pump(const Duration(milliseconds: 200));
|
await tester.pump(const Duration(milliseconds: 200));
|
||||||
final keyboardUpInputTop = tester.getTopLeft(composer).dy;
|
final keyboardUpInputTop = tester.getTopLeft(composer).dy;
|
||||||
final keyboardUpBottom = tester.getBottomLeft(composer).dy;
|
final keyboardUpBottom = tester.getBottomLeft(composer).dy;
|
||||||
@@ -497,11 +547,14 @@ void main() {
|
|||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(composer, findsOneWidget);
|
expect(composer, findsOneWidget);
|
||||||
expect(tester.getBottomLeft(composer).dy, closeTo(844, 0.1));
|
expect(tester.getBottomLeft(composer).dy, closeTo(844, 0.1));
|
||||||
|
debugDefaultTargetPlatformOverride = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'should_keep_composer_input_position_when_safe_area_padding_changes',
|
'should_keep_composer_input_position_when_safe_area_padding_changes',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
|
debugDefaultTargetPlatformOverride = TargetPlatform.android;
|
||||||
|
addTearDown(() => debugDefaultTargetPlatformOverride = null);
|
||||||
tester.view.physicalSize = const Size(390, 844);
|
tester.view.physicalSize = const Size(390, 844);
|
||||||
tester.view.devicePixelRatio = 1;
|
tester.view.devicePixelRatio = 1;
|
||||||
tester.view.padding = const FakeViewPadding();
|
tester.view.padding = const FakeViewPadding();
|
||||||
@@ -525,6 +578,7 @@ void main() {
|
|||||||
tester.view.viewInsets = const FakeViewPadding(bottom: 180);
|
tester.view.viewInsets = const FakeViewPadding(bottom: 180);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump(const Duration(milliseconds: 90));
|
await tester.pump(const Duration(milliseconds: 90));
|
||||||
|
await tester.pump(const Duration(milliseconds: 200));
|
||||||
final keyboardUpInputRect = tester.getRect(input);
|
final keyboardUpInputRect = tester.getRect(input);
|
||||||
|
|
||||||
tester.view.viewInsets = const FakeViewPadding();
|
tester.view.viewInsets = const FakeViewPadding();
|
||||||
@@ -544,12 +598,15 @@ void main() {
|
|||||||
keyboardClosedInputRect.height,
|
keyboardClosedInputRect.height,
|
||||||
closeTo(keyboardUpInputRect.height, 0.1),
|
closeTo(keyboardUpInputRect.height, 0.1),
|
||||||
);
|
);
|
||||||
|
debugDefaultTargetPlatformOverride = null;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'should_keep_composer_position_when_keyboard_insets_change_after_settling',
|
'should_keep_composer_position_when_keyboard_insets_change_after_settling',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
|
debugDefaultTargetPlatformOverride = TargetPlatform.android;
|
||||||
|
addTearDown(() => debugDefaultTargetPlatformOverride = null);
|
||||||
tester.view.physicalSize = const Size(390, 2200);
|
tester.view.physicalSize = const Size(390, 2200);
|
||||||
tester.view.devicePixelRatio = 1;
|
tester.view.devicePixelRatio = 1;
|
||||||
addTearDown(tester.view.resetPhysicalSize);
|
addTearDown(tester.view.resetPhysicalSize);
|
||||||
@@ -573,6 +630,7 @@ void main() {
|
|||||||
tester.view.viewInsets = const FakeViewPadding(bottom: 1100);
|
tester.view.viewInsets = const FakeViewPadding(bottom: 1100);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump(const Duration(milliseconds: 90));
|
await tester.pump(const Duration(milliseconds: 90));
|
||||||
|
await tester.pump(const Duration(milliseconds: 200));
|
||||||
final settledTop = tester.getTopLeft(composer).dy;
|
final settledTop = tester.getTopLeft(composer).dy;
|
||||||
final settledBottom = tester.getBottomLeft(composer).dy;
|
final settledBottom = tester.getBottomLeft(composer).dy;
|
||||||
final settledHeight = tester.getSize(composer).height;
|
final settledHeight = tester.getSize(composer).height;
|
||||||
@@ -598,6 +656,7 @@ void main() {
|
|||||||
expect(tester.getTopLeft(composer).dy, closeTo(settledTop, 0.1));
|
expect(tester.getTopLeft(composer).dy, closeTo(settledTop, 0.1));
|
||||||
expect(tester.getBottomLeft(composer).dy, closeTo(settledBottom, 0.1));
|
expect(tester.getBottomLeft(composer).dy, closeTo(settledBottom, 0.1));
|
||||||
expect(tester.getSize(composer).height, closeTo(settledHeight, 0.1));
|
expect(tester.getSize(composer).height, closeTo(settledHeight, 0.1));
|
||||||
|
debugDefaultTargetPlatformOverride = null;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user