【问题标题】:Jetpack Compose - stop focused elements from stealing back presses?Jetpack Compose - 阻止重点元素窃取背压?
【发布时间】:2021-09-26 15:20:53
【问题描述】:

我有一些元素在底部工作表中具有焦点。我想在按下系统后退按钮时折叠底部工作表,这很容易:

  BackHandler(enabled = bottomSheetState.isExpanded) {
    scope.launch {
      bottomSheetState.collapse()
    }
  }

问题是,如果一个元素在底部工作表中获得焦点,则返回处理程序的逻辑只有在按下返回按钮两次后才会被触发:一次从元素中移除焦点(轮廓文本字段)并再次触发崩溃。

我已经尝试使用LocalFocusManager.current 结合在按下返回时清除焦点,但是在元素已经失去焦点之前不会触发返回逻辑。

我可以清楚地关注折叠,所以我猜真正的问题是当工作表 1)可见和 2)有一个子元素聚焦时必须按两次。

有没有办法阻止重点元素取代我的逻辑?

【问题讨论】:

  • 找到任何解决此@Carter 的方法?
  • 我还没有找到。它有点落在我的问题列表的底部,但如果我弄明白了,我会更新。

标签: android-jetpack-compose android-jetpack-compose-scaffold


【解决方案1】:

嗨@Carter,我在官方跟踪器上找到了这个问题,找到链接here。它已在compose 1.1.0-alpha03 中修复,但由于该库是一个 alpha 候选版本,我不知道它对生产来说有多安全。还有一个提到的解决方法here

更简洁的方法是:

  1. 创建此经理
/***
 * Compose issue to be fixed in alpha 1.03
 * track from here : https://issuetracker.google.com/issues/192433071?pli=1
 * current work around
 */
class KeyBoardManager(context: Context) {

    private val activity = context as Activity
    private var keyboardDismissListener: KeyboardDismissListener? = null

    private abstract class KeyboardDismissListener(
        private val rootView: View,
        private val onKeyboardDismiss: () -> Unit
    ) : ViewTreeObserver.OnGlobalLayoutListener {
        private var isKeyboardClosed: Boolean = false
        override fun onGlobalLayout() {
            val r = Rect()
            rootView.getWindowVisibleDisplayFrame(r)
            val screenHeight = rootView.rootView.height
            val keypadHeight = screenHeight - r.bottom
            if (keypadHeight > screenHeight * 0.15) {
                // 0.15 ratio is right enough to determine keypad height.
                isKeyboardClosed = false
            } else if (!isKeyboardClosed) {
                isKeyboardClosed = true
                onKeyboardDismiss.invoke()
            }
        }
    }

    fun attachKeyboardDismissListener(onKeyboardDismiss: () -> Unit) {
        val rootView = activity.findViewById<View>(android.R.id.content)
        keyboardDismissListener = object : KeyboardDismissListener(rootView, onKeyboardDismiss) {}
        keyboardDismissListener?.let {
            rootView.viewTreeObserver.addOnGlobalLayoutListener(it)
        }
    }

    fun release() {
        val rootView = activity.findViewById<View>(android.R.id.content)
        keyboardDismissListener?.let {
            rootView.viewTreeObserver.removeOnGlobalLayoutListener(it)
        }
        keyboardDismissListener = null
    }
}
  1. 创建这个可组合的
@Composable
fun AppKeyboardFocusManager() {
    val context = LocalContext.current
    val focusManager = LocalFocusManager.current
    DisposableEffect(key1 = context) {
        val keyboardManager = KeyBoardManager(context)
        keyboardManager.attachKeyboardDismissListener {
            focusManager.clearFocus()
        }
        onDispose {
            keyboardManager.release()
        }
    }
}
  1. 在应用级别申请
setContent {
        AppKeyboardFocusManager()
        YourAppMaterialTheme {
            ...
        }
    }

【讨论】:

    猜你喜欢
    • 2022-10-05
    • 2021-09-12
    • 1970-01-01
    • 2011-03-15
    • 2018-04-24
    • 1970-01-01
    • 2022-12-12
    • 1970-01-01
    • 2011-11-04
    相关资源
    最近更新 更多