3

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

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

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

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

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

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

4

1 回答 1

1

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

更清洁的方法是:

  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 {
            ...
        }
    }
于 2021-09-26T07:20:53.850 回答