[英]Calling methods of InputMethodService from Jetpack Compose
Trying to make a custom Keyboard using Jetpack Compose.尝试使用 Jetpack Compose 制作自定义键盘。 Cannot figure out how call
currentInputConnection
or other methods from Composable.无法弄清楚如何从 Composable 调用
currentInputConnection
或其他方法。
@Composable
fun CustomKeyboard() {
var inputVal by remember { mutableStateOf("") }
Column(
modifier = Modifier
.fillMaxSize()
.padding(8.dp)
) {
Spacer(modifier = Modifier.height(50.dp))
Text("Last key pressed: $inputVal")
Row(modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically)
{
MyButton(mText = "A") { inputVal = it}
MyButton(mText = "B") { inputVal = it}
MyButton(mText = "C") { inputVal = it}
}
}
}
@Composable
private fun MyButton(
mText: String,
onPressed: (String) -> Unit
) {
OutlinedButton(
onClick = {
onPressed(mText)
},
modifier = Modifier.padding(4.dp)
) {
Text(text = mText, fontSize = 30.sp, color = Color.White)
}
}
And the InputMethodService class here...这里的 InputMethodService 类...
class ComposeKeyboardView(context: Context) : AbstractComposeView(context) {
@Composable
override fun Content() {
CustomKeyboard()
}
}
class IMEService : InputMethodService(), LifecycleOwner, ViewModelStoreOwner,
SavedStateRegistryOwner {
override fun onCreateInputView(): View {
val view = ComposeKeyboardView(this)
window!!.window!!.decorView.let { decorView ->
ViewTreeLifecycleOwner.set(decorView, this)
ViewTreeViewModelStoreOwner.set(decorView, this)
ViewTreeSavedStateRegistryOwner.set(decorView, this)
}
view.let {
ViewTreeLifecycleOwner.set(it, this)
ViewTreeViewModelStoreOwner.set(it, this)
ViewTreeSavedStateRegistryOwner.set(it, this)
}
return view
}
fun doSomethingWith(mData: String) {
currentInputConnection?.commitText(mData, 1)
}
//Lifecylce Methods
private var lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
private fun handleLifecycleEvent(event: Lifecycle.Event) =
lifecycleRegistry.handleLifecycleEvent(event)
override fun onCreate() {
super.onCreate()
savedStateRegistry.performRestore(null)
handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
}
override fun onDestroy() {
super.onDestroy()
handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
}
//ViewModelStore Methods
private val store = ViewModelStore()
override fun getViewModelStore(): ViewModelStore = store
//SaveStateRegestry Methods
private val savedStateRegistry = SavedStateRegistryController.create(this)
override fun getSavedStateRegistry(): SavedStateRegistry = savedStateRegistry.savedStateRegistry
}
If you just need to call a single function, ie doSomethingWith(mData: String)
, or a few of them, then you can pass them into your composables and call them when you want to.如果您只需要调用一个函数,即
doSomethingWith(mData: String)
或其中的几个,那么您可以将它们传递到您的可组合项中,并在需要时调用它们。 This approach would be more loosely coupled and easier to @Preview
the CustomKeyboard
composable.这种方法将更加松散耦合,并且更容易
@Preview
CustomKeyboard
可组合。
@Composable
fun CustomKeyboard(onKeyPressed: (String) -> Unit) {
//...
MyButton(mText = "A") {
inputVal = it
onKeyPressed(it)
}
// ...
}
class ComposeKeyboardView(
context: Context,
private val onKeyPressed: (String) -> Unit,
) : AbstractComposeView(context) {
@Composable
override fun Content() {
CustomKeyboard(onKeyPressed)
}
}
class IMEService : InputMethodService() {
override fun onCreateInputView(): View {
val view = ComposeKeyboardView(this, onKeyPressed = this::doSomethingWith)
// ...
return view
}
private fun doSomethingWith(mData: String) {
currentInputConnection?.commitText(mData, 1)
}
}
If you plan to add many more functions to the IMEService
that you will have to also call, then you can just pass the IMEService
(or some interface that IMEService
implements) into your composables and then call its members normally.如果您计划向
IMEService
添加更多必须调用的功能,那么您可以将IMEService
(或IMEService
实现的某些接口)传递到您的可组合项中,然后正常调用其成员。 Using an interface over an actual class would make it possible to @Preview
the CustomKeyboard
composable.在实际类上使用接口可以
@Preview
CustomKeyboard
可组合。
@Composable
fun CustomKeyboard(imeService: IMEService) {
//...
MyButton(mText = "A") {
inputVal = it
imeService.doSomethingWith(it)
}
// ...
}
class ComposeKeyboardView(private val imeService: IMEService) : AbstractComposeView(imeService) {
@Composable
override fun Content() {
CustomKeyboard(imeService)
}
}
class IMEService : InputMethodService() {
override fun onCreateInputView(): View {
val view = ComposeKeyboardView(this)
// ...
return view
}
fun doSomethingWith(mData: String) {
currentInputConnection?.commitText(mData, 1)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.