首页 > 解决方案 > 回按时Android隐藏键盘并关闭bottomsheetfragment

问题描述

我在bottomsheetfragment通过单击后隐藏键盘和键盘时遇到问题。当前的实现要求用户单击两次以关闭键盘和底页。

我实现setOnKeyListener但第一次后退单击隐藏键盘和第二次单击触发后退事件

视频链接

对话风格

 <style name="BottomSheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
        <item name="android:windowIsFloating">false</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:windowSoftInputMode">adjustResize</item>
    </style>

class CommentInputFragment : BottomSheetDialogFragment() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
     setStyle(DialogFragment.STYLE_NORMAL, R.style.BottomSheetDialog);


}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    var view= inflater.inflate(R.layout.fragment_comment_input, container, false)
    return view;
}

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    var dialog= super.onCreateDialog(savedInstanceState)

    return dialog

}

override fun onResume() {
    super.onResume()

    dialog?.setOnKeyListener(object: DialogInterface.OnKeyListener
    {
        override fun onKey(p0: DialogInterface?, keyCode: Int, p2: KeyEvent?): Boolean {
            if ((keyCode ==  android.view.KeyEvent.KEYCODE_BACK))
            {
                // To dismiss the fragment when the back-button is pressed.
                dismiss();
                return true;
            }
            // Otherwise, do nothing else
            else return false;
        }
    })
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    et_add_comment.requestFocus();
}


}

标签: androidkotlinandroid-softkeyboardbottomsheetdialogfragmentonkeylistener

解决方案


问题:

如果您注意到后退箭头指向底部(在最近的设备中)而不是左侧,则在这种情况下,对话框不会拦截后按,因为它是由软键盘触发的。dialog?.setOnKeyListener因此不会触发的回调。

所以,你需要通过一些键盘监听器来拦截按键事件;好吧,对于这里那里的许多帖子来说,这是一个挑战,并且每个解决方案都可以在特定情况下工作。

解决方案

当被调用时,我们将ViewGroupBottomSheetFragment布局的根 ( R.layout.fragment_comment_input)中注册一个监听器。dispatchKeyEventPreIme()这会为附加到此布局的关键事件调用。

创建监听器:

interface OnBackPressListener {
    fun onBackPressed(event: KeyEvent)
}

因此,作为根目录FrameLayout,然后对其进行自定义:

class DispatchKeyFrameLayout @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    private var listener: OnBackPressListener? = null

    fun setOnBackPressListener (listener: OnBackPressListener) {
        this.listener = listener
    }

    override fun dispatchKeyEventPreIme(event: KeyEvent): Boolean {
        // Trigger the listener callback
        listener?.onBackPressed(event)
        return super.dispatchKeyEventPreIme(event)
    }
}

并将其用作以下中的根布局R.layout.fragment_comment_input

<com.example.kotlintest.DispatchKeyFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<!--Other views-->

</com.example.kotlintest.DispatchKeyFrameLayout>

然后将侦听器设置BottomSheetFragment onResume()为关闭对话框。

override fun onResume() {
    super.onResume()

    layout.setOnBackPressListener(object : OnBackPressListener{
        override fun onBackPressed(event: KeyEvent) {
            if (event.keyCode == android.view.KeyEvent.KEYCODE_BACK)
                dismiss()
        }
    })
}

现在您可以安全地删除dialog?.setOnKeyListener

预习:


推荐阅读