Skip to content

Commit 8825177

Browse files
committed
refactor: implement window manager to manage all kinds of keyboard window
Expose keyboardHeight from Keyboard to set the keyboard view area height in InputView
1 parent a3d9290 commit 8825177

File tree

9 files changed

+203
-49
lines changed

9 files changed

+203
-49
lines changed

app/src/main/java/com/osfans/trime/ime/core/InputView.kt

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class InputView(
8787

8888
private val themedContext = context.withTheme(android.R.style.Theme_DeviceDefault_Settings)
8989
private val inputComponent = InputComponent::class.create(themedContext, theme, service)
90+
private val windowManager = inputComponent.windowManager
9091
val quickBar: QuickBar = inputComponent.quickBar
9192
val keyboardWindow: KeyboardWindow = inputComponent.keyboardWindow
9293
val liquidKeyboard: LiquidKeyboard = inputComponent.liquidKeyboard
@@ -126,6 +127,9 @@ class InputView(
126127
}
127128
}
128129

130+
windowManager.cacheResidentWindow(keyboardWindow, createView = true)
131+
windowManager.cacheResidentWindow(liquidKeyboard)
132+
129133
service.window.window!!.also { it ->
130134
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
131135
shouldUpdateNavbarForeground = true
@@ -154,8 +158,6 @@ class InputView(
154158
}
155159
}
156160

157-
liquidKeyboard.setKeyboardView(keyboardWindow.oldSymbolInputView.liquidKeyboardView)
158-
159161
keyboardBackground.imageDrawable = ColorManager.getDrawable("keyboard_background")
160162
?: ColorManager.getDrawable("keyboard_back_color")
161163

@@ -192,7 +194,7 @@ class InputView(
192194
},
193195
)
194196
add(
195-
keyboardWindow.view,
197+
windowManager.view,
196198
lParams(matchParent, wrapContent) {
197199
below(quickBar.view)
198200
above(bottomPaddingSpace)
@@ -229,7 +231,7 @@ class InputView(
229231
// hide side padding space views when unnecessary
230232
leftPaddingSpace.visibility = View.GONE
231233
rightPaddingSpace.visibility = View.GONE
232-
keyboardWindow.view.updateLayoutParams<LayoutParams> {
234+
windowManager.view.updateLayoutParams<LayoutParams> {
233235
startToEnd = unset
234236
endToStart = unset
235237
startOfParent()
@@ -244,7 +246,7 @@ class InputView(
244246
rightPaddingSpace.updateLayoutParams {
245247
width = sidePadding
246248
}
247-
keyboardWindow.view.updateLayoutParams<LayoutParams> {
249+
windowManager.view.updateLayoutParams<LayoutParams> {
248250
startToStart = unset
249251
endToEnd = unset
250252
startToEndOf(leftPaddingSpace)
@@ -273,6 +275,9 @@ class InputView(
273275
}
274276
}
275277
keyboardWindow.oldMainInputView.mainKeyboardView.updateEnterLabelOnEditorInfo(info)
278+
if (!restarting) {
279+
windowManager.attachWindow(KeyboardWindow)
280+
}
276281
}
277282

278283
private fun handleRimeNotification(it: RimeNotification) {
@@ -297,9 +302,18 @@ class InputView(
297302
}
298303
}
299304

300-
fun switchUiByState(state: KeyboardWindow.State) {
301-
keyboardWindow.switchUiByState(state)
302-
quickBar.switchUiByState(QuickBar.State.entries[state.ordinal])
305+
enum class Board {
306+
Main,
307+
Symbol,
308+
}
309+
310+
fun switchBoard(board: Board) {
311+
when (board) {
312+
Board.Main -> windowManager.attachWindow(keyboardWindow)
313+
Board.Symbol -> windowManager.attachWindow(liquidKeyboard)
314+
}
315+
quickBar.switchUiByState(QuickBar.State.entries[board.ordinal])
316+
updateKeyboardSize()
303317
}
304318

305319
private var showingDialog: Dialog? = null

app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ import com.osfans.trime.ime.keyboard.InputFeedbackManager
6262
import com.osfans.trime.ime.keyboard.Key
6363
import com.osfans.trime.ime.keyboard.KeyboardSwitcher
6464
import com.osfans.trime.ime.keyboard.KeyboardView
65-
import com.osfans.trime.ime.keyboard.KeyboardWindow
6665
import com.osfans.trime.ime.symbol.TabManager
6766
import com.osfans.trime.ime.symbol.TabView
6867
import com.osfans.trime.ime.text.Candidate
@@ -230,7 +229,6 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
230229
// could crash
231230
// and lead to a crash loop
232231
Timber.d("onCreate")
233-
val context: InputMethodService = this
234232
ColorManager.addOnChangedListener(onColorChangeListener)
235233
RimeWrapper.startup {
236234
Timber.d("Running Trime.onCreate")
@@ -267,7 +265,7 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
267265
fun selectLiquidKeyboard(tabIndex: Int) {
268266
if (inputView == null) return
269267
if (tabIndex >= 0) {
270-
inputView!!.switchUiByState(KeyboardWindow.State.Symbol)
268+
inputView!!.switchBoard(InputView.Board.Symbol)
271269
symbolKeyboardType = inputView!!.liquidKeyboard.select(tabIndex)
272270
tabView!!.updateTabWidth()
273271
mTabRoot!!.move(tabView!!.highlightLeft, tabView!!.highlightRight)
@@ -277,7 +275,7 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
277275
symbolKeyboardType = SymbolKeyboardType.NO_KEY
278276
// 设置液体键盘处于隐藏状态
279277
TabManager.setTabExited()
280-
inputView!!.switchUiByState(KeyboardWindow.State.Main)
278+
inputView!!.switchBoard(InputView.Board.Main)
281279
updateComposing()
282280
}
283281
}

app/src/main/java/com/osfans/trime/ime/dependency/InputComponent.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@ import com.osfans.trime.ime.bar.QuickBar
66
import com.osfans.trime.ime.core.TrimeInputMethodService
77
import com.osfans.trime.ime.keyboard.KeyboardWindow
88
import com.osfans.trime.ime.symbol.LiquidKeyboard
9+
import com.osfans.trime.ime.window.BoardWindowManager
910
import me.tatarka.inject.annotations.Component
1011
import me.tatarka.inject.annotations.Provides
1112

1213
@InputScope
1314
@Component
1415
abstract class InputComponent(
15-
@get:InputScope @get:Provides protected val themedContext: Context,
16-
@get:InputScope @get:Provides protected val theme: Theme,
17-
@get:InputScope @get:Provides protected val service: TrimeInputMethodService,
16+
@get:InputScope @get:Provides val themedContext: Context,
17+
@get:InputScope @get:Provides val theme: Theme,
18+
@get:InputScope @get:Provides val service: TrimeInputMethodService,
1819
) {
1920
abstract val quickBar: QuickBar
21+
abstract val windowManager: BoardWindowManager
2022
abstract val keyboardWindow: KeyboardWindow
2123
abstract val liquidKeyboard: LiquidKeyboard
2224
}

app/src/main/java/com/osfans/trime/ime/keyboard/Keyboard.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,10 @@ class Keyboard() {
105105
private set
106106
var asciiKeyboard: String? = null // 英文鍵盤
107107
private set
108+
108109
// todo 把按下按键弹出的内容改为单独设计的view,而不是keyboard
110+
var keyboardHeight: Int = 0
111+
private set
109112

110113
/**
111114
* Creates a blank keyboard from the given resource file and populates it with the specified
@@ -222,7 +225,7 @@ class Keyboard() {
222225
)
223226
val horizontalGap = horizontalGap
224227
val verticalGap = verticalGap
225-
val keyboardHeight = getKeyboardHeight(theme, keyboardConfig)
228+
keyboardHeight = getKeyboardHeight(theme, keyboardConfig)
226229
val keyboardKeyWidth = obtainFloat(keyboardConfig, "width", 0f)
227230
val maxColumns = if (columns == -1) Int.MAX_VALUE else columns
228231
var x = this.horizontalGap / 2

app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardWindow.kt

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,35 @@ package com.osfans.trime.ime.keyboard
22

33
import android.content.Context
44
import android.view.LayoutInflater
5-
import android.widget.ViewAnimator
5+
import android.view.View
66
import com.osfans.trime.databinding.MainInputLayoutBinding
7-
import com.osfans.trime.databinding.SymbolInputLayoutBinding
87
import com.osfans.trime.ime.core.TrimeInputMethodService
98
import com.osfans.trime.ime.dependency.InputScope
9+
import com.osfans.trime.ime.window.BoardWindow
10+
import com.osfans.trime.ime.window.ResidentWindow
1011
import me.tatarka.inject.annotations.Inject
11-
import splitties.views.dsl.core.add
12-
import splitties.views.dsl.core.lParams
13-
import splitties.views.dsl.core.matchParent
1412

1513
@InputScope
1614
@Inject
17-
class KeyboardWindow(context: Context, service: TrimeInputMethodService) {
15+
class KeyboardWindow(context: Context, private val service: TrimeInputMethodService) : BoardWindow.NoBarBoardWindow(), ResidentWindow {
1816
val oldMainInputView by lazy {
19-
MainInputLayoutBinding.inflate(LayoutInflater.from(context)).apply {
20-
mainKeyboardView.onKeyboardActionListener = service.textInputManager
21-
}
17+
MainInputLayoutBinding.inflate(LayoutInflater.from(context))
2218
}
2319

24-
val oldSymbolInputView by lazy {
25-
SymbolInputLayoutBinding.inflate(LayoutInflater.from(context))
26-
}
20+
companion object : ResidentWindow.Key
21+
22+
override val key: ResidentWindow.Key
23+
get() = KeyboardWindow
2724

28-
enum class State {
29-
Main,
30-
Symbol,
25+
override fun onCreateView(): View {
26+
return oldMainInputView.root
3127
}
3228

33-
fun switchUiByState(state: State) {
34-
if (view.displayedChild == state.ordinal) return
35-
view.displayedChild = state.ordinal
29+
override fun onAttached() {
30+
oldMainInputView.mainKeyboardView.onKeyboardActionListener = service.textInputManager
3631
}
3732

38-
val view by lazy {
39-
ViewAnimator(context).apply {
40-
add(oldMainInputView.root, lParams(matchParent, matchParent))
41-
add(oldSymbolInputView.root, lParams(matchParent, matchParent))
42-
}
33+
override fun onDetached() {
34+
oldMainInputView.mainKeyboardView.onKeyboardActionListener = null
4335
}
4436
}

app/src/main/java/com/osfans/trime/ime/symbol/LiquidKeyboard.kt

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package com.osfans.trime.ime.symbol
22

33
import android.app.AlertDialog
44
import android.content.Context
5+
import android.view.View
56
import androidx.core.view.setPadding
67
import androidx.lifecycle.lifecycleScope
78
import androidx.recyclerview.widget.LinearLayoutManager
8-
import androidx.recyclerview.widget.RecyclerView
99
import androidx.recyclerview.widget.StaggeredGridLayoutManager
1010
import com.google.android.flexbox.FlexDirection
1111
import com.google.android.flexbox.FlexWrap
@@ -24,11 +24,20 @@ import com.osfans.trime.ime.core.TrimeInputMethodService
2424
import com.osfans.trime.ime.dependency.InputScope
2525
import com.osfans.trime.ime.enums.KeyCommandType
2626
import com.osfans.trime.ime.enums.SymbolKeyboardType
27+
import com.osfans.trime.ime.keyboard.KeyboardSwitcher
2728
import com.osfans.trime.ime.text.TextInputManager
29+
import com.osfans.trime.ime.window.BoardWindow
30+
import com.osfans.trime.ime.window.ResidentWindow
2831
import com.osfans.trime.util.ShortcutUtils
2932
import kotlinx.coroutines.launch
3033
import me.tatarka.inject.annotations.Inject
3134
import splitties.dimensions.dp
35+
import splitties.views.dsl.constraintlayout.centerInParent
36+
import splitties.views.dsl.constraintlayout.constraintLayout
37+
import splitties.views.dsl.constraintlayout.lParams
38+
import splitties.views.dsl.core.add
39+
import splitties.views.dsl.core.matchParent
40+
import splitties.views.dsl.recyclerview.recyclerView
3241
import timber.log.Timber
3342

3443
@InputScope
@@ -37,8 +46,7 @@ class LiquidKeyboard(
3746
private val context: Context,
3847
private val service: TrimeInputMethodService,
3948
private val theme: Theme,
40-
) : ClipboardHelper.OnClipboardUpdateListener {
41-
private lateinit var keyboardView: RecyclerView
49+
) : BoardWindow.NoBarBoardWindow(), ResidentWindow, ClipboardHelper.OnClipboardUpdateListener {
4250
private val symbolHistory = SymbolHistory(180)
4351
private var adapterType: AdapterType = AdapterType.INIT
4452
private val simpleAdapter by lazy {
@@ -68,15 +76,33 @@ class LiquidKeyboard(
6876
CandidateAdapter(theme)
6977
}
7078

71-
fun setKeyboardView(view: RecyclerView) {
72-
keyboardView =
73-
view.apply {
74-
val space = view.dp(3)
75-
addItemDecoration(SpacesItemDecoration(space))
76-
setPadding(space)
77-
}
79+
companion object : ResidentWindow.Key
80+
81+
override val key: ResidentWindow.Key
82+
get() = LiquidKeyboard
83+
84+
private val keyboardView =
85+
context.recyclerView {
86+
val space = dp(3)
87+
addItemDecoration(SpacesItemDecoration(space))
88+
setPadding(space)
89+
}
90+
91+
override fun onCreateView(): View {
92+
return context.constraintLayout {
93+
add(
94+
keyboardView,
95+
lParams(matchParent, KeyboardSwitcher.currentKeyboard.keyboardHeight) {
96+
centerInParent()
97+
},
98+
)
99+
}
78100
}
79101

102+
override fun onAttached() {}
103+
104+
override fun onDetached() {}
105+
80106
// 及时更新layoutManager, 以防在旋转屏幕后打开液体键盘crash
81107

82108
/**
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.osfans.trime.ime.window
2+
3+
import android.view.View
4+
5+
sealed class BoardWindow {
6+
/**
7+
* After the window was set up in InputComponent
8+
*/
9+
abstract fun onCreateView(): View
10+
11+
/**
12+
* After the view was added to window manager's layout
13+
*/
14+
abstract fun onAttached()
15+
16+
/**
17+
* Before the view is removed from window manager's layout
18+
*/
19+
abstract fun onDetached()
20+
21+
abstract class NoBarBoardWindow : BoardWindow() {
22+
override fun toString(): String = javaClass.name
23+
}
24+
}

0 commit comments

Comments
 (0)