键盘上方的 BottomSheetDialog

BottomSheetDialog above the keyboard

如何在打开 BottomSheetDialog 时显示键盘并且对话框本身显示在键盘上方?并且 EditText 立即激活。

现在我的对话框是这样的:

我想在这里点赞:

这是我的代码:

abstract class CustomDialog(@LayoutRes layout: Int) : DialogFragment() {
    val layoutDialog = layout
    val dialogView: View? by lazy { View.inflate(activity, layout, null) as ViewGroup }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return dialogView
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val bottomSheetDialog = BottomSheetDialog(requireActivity(), R.style.BottomSheetDialogTheme)
        val bottomSheetView = LayoutInflater.from(context).inflate(layoutDialog, null)
        bottomSheetDialog.setContentView(bottomSheetView)

        return bottomSheetDialog
    }
}

创建对话框:

class CreateTaskDialog() : CustomDialog(R.layout.dialog_add_task) {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }
}

我在这里显示对话框:

requireActivity().showDialog(CreateTaskDialog())

fun FragmentActivity.showDialog(dialog: DialogFragment, tag: String? = null)
        = dialog.show(this.supportFragmentManager, tag)

这是风格:

<style name="BottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/BottomSheetStyle</item>
</style>

<style name="BottomSheetStyle" parent="Widget.Design.BottomSheet.Modal">
    <item name="android:windowIsFloating">false</item>
    <item name="android:windowSoftInputMode">adjustResize</item>
    <item name="android:background">@android:color/transparent</item>
</style>

解决方案并不明显)我已经搜索了整个 Whosebug。我找到了几种解决方案,但其中 none 对我有所帮助,直到我制作了如下样式(一个立即带有圆角边缘的示例):

<style name="BottomSheetDialogKeyboardTheme" parent="Theme.MaterialComponents.DayNight.BottomSheetDialog">
    <item name="android:windowIsFloating">false</item>
    <item name="android:windowSoftInputMode">adjustResize</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:background">@android:color/transparent</item>
    <item name="shapeAppearanceOverlay">@style/ShapeBottomSheetDialogKeyboard</item>
</style>

<style name="ShapeBottomSheetDialogKeyboard" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">16dp</item>
    <item name="cornerSizeTopLeft">16dp</item>
    <item name="cornerSizeBottomRight">0dp</item>
    <item name="cornerSizeBottomLeft">0dp</item>
</style>

创建片段时,我也添加了这样一个时刻(尽管没有它也可以正常工作):

val bottomSheet = bottomSheetDialog.window?.decorView?.findViewById<FrameLayout>(R.id.design_bottom_sheet) as FrameLayout
val mBehavior = BottomSheetBehavior.from(bottomSheet)
mBehavior.state = BottomSheetBehavior.STATE_EXPANDED

要应用圆边样式,我必须添加如下代码:

val newMaterialShapeDrawable: MaterialShapeDrawable = createMaterialShapeDrawable(requireContext(), bottomSheet)
                ViewCompat.setBackground(bottomSheet, newMaterialShapeDrawable)

fun createMaterialShapeDrawable(context: Context, bottomSheet: View): MaterialShapeDrawable {
    val shapeAppearanceModel = ShapeAppearanceModel
        .builder(context, 0, R.style.ShapeBottomSheetDialogKeyboard)
        .build()

    val currentMaterialShapeDrawable = bottomSheet.background as MaterialShapeDrawable
    val newMaterialShapeDrawable = MaterialShapeDrawable(shapeAppearanceModel)

    newMaterialShapeDrawable.initializeElevationOverlay(context)
    newMaterialShapeDrawable.fillColor = currentMaterialShapeDrawable.fillColor
    newMaterialShapeDrawable.tintList = currentMaterialShapeDrawable.tintList
    newMaterialShapeDrawable.elevation = currentMaterialShapeDrawable.elevation
    newMaterialShapeDrawable.strokeWidth = currentMaterialShapeDrawable.strokeWidth
    newMaterialShapeDrawable.strokeColor = currentMaterialShapeDrawable.strokeColor

    return newMaterialShapeDrawable
}

整个 CustomDialog 代码变成了这样:

abstract class CustomDialogKeyboard(@LayoutRes layout: Int) : BottomSheetDialogFragment() {

    private val layoutDialog = layout
    private lateinit var mBehavior: BottomSheetBehavior<FrameLayout>

    val dialogView: View? by lazy { View.inflate(activity, layout, null) as ViewGroup }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return dialogView
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val bottomSheetDialog = BottomSheetDialog(requireActivity(), R.style.BottomSheetDialogKeyboardTheme)
        val bottomSheetView = LayoutInflater.from(context).inflate(layoutDialog, null)
        bottomSheetDialog.setContentView(bottomSheetView)

        bottomSheetDialog.setOnShowListener {
            try {
                val bottomSheet = bottomSheetDialog.window?.decorView?.findViewById<FrameLayout>(R.id.design_bottom_sheet) as FrameLayout
                mBehavior = BottomSheetBehavior.from(bottomSheet)
                mBehavior.state = BottomSheetBehavior.STATE_EXPANDED

                val newMaterialShapeDrawable: MaterialShapeDrawable = createMaterialShapeDrawable(requireContext(), bottomSheet)
                ViewCompat.setBackground(bottomSheet, newMaterialShapeDrawable)
            } catch (e: Exception) {}
        }

        return bottomSheetDialog
    }
}