Flutter 再论编辑器的键盘处理

Posted by koocyton on 2024-11-29
Estimated Reading Time 2 Minutes
Words 439 In Total
Viewed Times

Flutter 编辑器键盘处理

简介

| 不能说终极版吧
| 比网易,讯飞AI 的编辑器处理得更好

主要逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// 这里差点意思,不能和屏幕刷新同频,不太自然
// 最好还是借助 animation 来处理,但互相干扰,处理比较麻烦
// menubar 滑入
void slideinMenubar(int x) {
double m = maxToolbarHeight ?? ui.windowHeight * 0.382;
toolbarHeight = toolbarHeight + x;
if (toolbarHeight>=m-10) {
toolbarHeight = m;
setStatus();
}
else {
setStatus();
Future.delayed(const Duration(milliseconds: 1), (){
slideinMenubar(x);
});
}
}

// menubar 滑出
void slideoutMenubar(int x) {
toolbarHeight = toolbarHeight - x;
if (toolbarHeight<=10) {
toolbarHeight = 0;
setStatus();
}
else {
setStatus();
Future.delayed(const Duration(milliseconds: 1), (){
slideoutMenubar(x);
});
}
}

// 切换 menuLabel
void changeMenuLabel(BuildContext context, int choiceMenuLabel) {
currentMenuLabel = choiceMenuLabel;
// 菜单在底部
if (toolbarHeight<=0) {
isLockKeyboardBottom = selectedMenuLabel= true;
slideinMenubar(10);
}
// 菜单已弹起
else {
isLockKeyboardBottom = true;
selectedMenuLabel = false;
SystemChannels.textInput.invokeMethod<void>(
keyboardHeight<=0 ? 'TextInput.show' : 'TextInput.hide'
);
}
setStatus();
}

// 切换 返回
void onPopInvoked<T>(bool didPop, T? result) {
// 键盘&菜单在底部
if (toolbarHeight<=0) {
if (!didPop) {
saveThenExit();
}
}
// 键盘在底部, 菜单弹起
else if(keyboardHeight<=0) {
isLockKeyboardBottom = selectedMenuLabel = false;
setStatus();
slideoutMenubar(10);
}
// 键盘弹起, 菜单弹起
else {
isLockKeyboardBottom = false;
SystemChannels.textInput.invokeMethod<void>('TextInput.hide');
}
}

Duration? frameCallTime;

double lastKeyboardHeight = 0;

BuildContext? editContext;

void frameCallback(Duration callTime) {
if (editContext==null || (frameCallTime!=null && frameCallTime!.compareTo(callTime)==0)) {
return;
}
keyboardHeight = MediaQuery.of(editContext!).viewInsets.bottom;
// show begin
if (keyboardHeight > lastKeyboardHeight && lastKeyboardHeight <= 0) {
keyboardStatus = KeyboardStatus.showing;
selectedMenuLabel = false;
Future.delayed(const Duration(milliseconds: 270), (){
keyboardStatus = KeyboardStatus.show;
isLockKeyboardBottom = selectedMenuLabel = false;
toolbarHeight = keyboardHeight;
cacheMaxToolbarHeight(keyboardHeight);
setStatus();
});
}
// hide end
else if (keyboardHeight <= 0 && keyboardHeight < lastKeyboardHeight) {
keyboardStatus = KeyboardStatus.hide;
// 键盘在底部,说明是为了展示子菜单
selectedMenuLabel = isLockKeyboardBottom;
}
// 剩下的就是 hiding 和 sliding ( 软键盘切换形态使得高度变化 ) 了
else {
keyboardStatus = KeyboardStatus.sliding;
}
if (isLockKeyboardBottom==false || toolbarHeight<keyboardHeight) {
toolbarHeight = keyboardHeight;
}
lastKeyboardHeight = keyboardHeight;
frameCallTime = callTime;
setStatus();
}

如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !