fix: the content is blocked by the keyboard sometimes (#594)

* fix: the content is blocked by the keyboard sometimes

* chore: use flutter 3.13.9 in CI
This commit is contained in:
Lucas.Xu 2023-11-16 14:39:05 +08:00
commit 2617f766a5
5 changed files with 35 additions and 26 deletions

View file

@ -33,6 +33,7 @@ jobs:
- uses: subosito/flutter-action@v2 - uses: subosito/flutter-action@v2
with: with:
channel: "stable" channel: "stable"
flutter-version: "3.13.9"
cache: true cache: true
- name: Run tests - name: Run tests

View file

@ -49,6 +49,7 @@ class _MobileEditorState extends State<MobileEditor> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(PlatformExtension.isMobile); assert(PlatformExtension.isMobile);
return MobileToolbarV2( return MobileToolbarV2(
toolbarHeight: 48.0,
toolbarItems: [ toolbarItems: [
textDecorationMobileToolbarItemV2, textDecorationMobileToolbarItemV2,
buildTextAndBackgroundColorMobileToolbarItem(), buildTextAndBackgroundColorMobileToolbarItem(),

View file

@ -109,7 +109,7 @@ class _ScrollServiceWidgetState extends State<ScrollServiceWidget>
return Future.delayed(const Duration(milliseconds: 300), () { return Future.delayed(const Duration(milliseconds: 300), () {
startAutoScroll( startAutoScroll(
endTouchPoint, endTouchPoint,
edgeOffset: 50, edgeOffset: 100,
duration: Duration.zero, duration: Duration.zero,
); );
}); });

View file

@ -20,7 +20,7 @@ class MobileToolbarTheme extends InheritedWidget {
this.primaryColor = const Color(0xff1F71AC), this.primaryColor = const Color(0xff1F71AC),
this.onPrimaryColor = Colors.white, this.onPrimaryColor = Colors.white,
this.outlineColor = const Color(0xFFE3E3E3), this.outlineColor = const Color(0xFFE3E3E3),
this.toolbarHeight = 50.0, this.toolbarHeight = 48.0,
this.borderRadius = 6.0, this.borderRadius = 6.0,
this.buttonHeight = 40.0, this.buttonHeight = 40.0,
this.buttonSpacing = 8.0, this.buttonSpacing = 8.0,

View file

@ -7,13 +7,13 @@ class MobileToolbarV2 extends StatefulWidget {
super.key, super.key,
required this.editorState, required this.editorState,
required this.toolbarItems, required this.toolbarItems,
this.bottomOffset = 0.0, required this.toolbarHeight,
required this.child, required this.child,
}); });
final EditorState editorState; final EditorState editorState;
final List<MobileToolbarItem> toolbarItems; final List<MobileToolbarItem> toolbarItems;
final double bottomOffset; final double toolbarHeight;
final Widget child; final Widget child;
@override @override
@ -22,24 +22,45 @@ class MobileToolbarV2 extends StatefulWidget {
class _MobileToolbarV2State extends State<MobileToolbarV2> { class _MobileToolbarV2State extends State<MobileToolbarV2> {
OverlayEntry? toolbarOverlay; OverlayEntry? toolbarOverlay;
final keyboardHeightPlugin = KeyboardHeightPlugin();
final isKeyboardShow = ValueNotifier(false);
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_insertKeyboardToolbar(); _insertKeyboardToolbar();
keyboardHeightPlugin.onKeyboardHeightChanged((height) {
isKeyboardShow.value = height > 0;
});
} }
@override @override
void dispose() { void dispose() {
_removeKeyboardToolbar(); _removeKeyboardToolbar();
keyboardHeightPlugin.dispose();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return widget.child; return Column(
children: [
Expanded(
child: widget.child,
),
// add a bottom offset to make sure the toolbar is above the keyboard
ValueListenableBuilder(
valueListenable: isKeyboardShow,
builder: (context, isKeyboardShow, __) {
return SizedBox(
height: isKeyboardShow ? widget.toolbarHeight : 0,
);
},
),
],
);
} }
void _removeKeyboardToolbar() { void _removeKeyboardToolbar() {
@ -53,16 +74,21 @@ class _MobileToolbarV2State extends State<MobileToolbarV2> {
Widget child = ValueListenableBuilder<Selection?>( Widget child = ValueListenableBuilder<Selection?>(
valueListenable: widget.editorState.selectionNotifier, valueListenable: widget.editorState.selectionNotifier,
builder: (_, Selection? selection, child) { builder: (_, Selection? selection, __) {
// if the selection is null, hide the toolbar // if the selection is null, hide the toolbar
if (selection == null) { if (selection == null) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
Widget child = _MobileToolbar(
editorState: widget.editorState,
toolbarItems: widget.toolbarItems,
);
// if the MobileToolbarTheme is not provided, provide it // if the MobileToolbarTheme is not provided, provide it
if (MobileToolbarTheme.maybeOf(context) == null) { if (MobileToolbarTheme.maybeOf(context) == null) {
child = MobileToolbarTheme( child = MobileToolbarTheme(
child: child!, child: child,
); );
} }
@ -70,11 +96,6 @@ class _MobileToolbarV2State extends State<MobileToolbarV2> {
child: child, child: child,
); );
}, },
child: _MobileToolbar(
editorState: widget.editorState,
toolbarItems: widget.toolbarItems,
bottomOffset: widget.bottomOffset,
),
); );
child = Stack( child = Stack(
@ -106,12 +127,10 @@ class _MobileToolbar extends StatefulWidget {
const _MobileToolbar({ const _MobileToolbar({
required this.editorState, required this.editorState,
required this.toolbarItems, required this.toolbarItems,
required this.bottomOffset,
}); });
final EditorState editorState; final EditorState editorState;
final List<MobileToolbarItem> toolbarItems; final List<MobileToolbarItem> toolbarItems;
final double bottomOffset;
@override @override
State<_MobileToolbar> createState() => _MobileToolbarState(); State<_MobileToolbar> createState() => _MobileToolbarState();
@ -127,9 +146,6 @@ class _MobileToolbarState extends State<_MobileToolbar>
// This is because we want to keep the same height when the menu is shown. // This is because we want to keep the same height when the menu is shown.
bool canUpdateCachedKeyboardHeight = true; bool canUpdateCachedKeyboardHeight = true;
ValueNotifier<double> cachedKeyboardHeight = ValueNotifier(0.0); ValueNotifier<double> cachedKeyboardHeight = ValueNotifier(0.0);
double get keyboardHeight => MediaQuery.of(context).viewInsets.bottom;
double get safeAreaBottomPadding => MediaQuery.of(context).viewPadding.bottom;
final keyboardHeightPlugin = KeyboardHeightPlugin(); final keyboardHeightPlugin = KeyboardHeightPlugin();
// used to check if click the same item again // used to check if click the same item again
@ -179,15 +195,6 @@ class _MobileToolbarState extends State<_MobileToolbar>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// update the keyboard height here.
// try to get the height in `didChangeMetrics`, but it's not accurate.
if (canUpdateCachedKeyboardHeight) {
// cachedKeyboardHeight.value = max(
// 0,
// keyboardHeight - safeAreaBottomPadding - widget.bottomOffset,
// );
// print('cachedKeyboardHeight: ${cachedKeyboardHeight.value}');
}
// toolbar // toolbar
// - if the menu is shown, the toolbar will be pushed up by the height of the menu // - if the menu is shown, the toolbar will be pushed up by the height of the menu
// - otherwise, add a spacer to push the toolbar up when the keyboard is shown // - otherwise, add a spacer to push the toolbar up when the keyboard is shown