0

I'm implementing BottomSheetDialogFragment to my app, but sometimes as I open BottomSheet, it will get stuck inbetween bottom edge of visible display. I even checked LayoutInspector and half of the dialog view is below visible display.

I even added this "trick" I found in this post into onCreateDialog but its not working at all.

Here is my Bottomsheet:

open class FragmentBottomsheet(
    private val a: BaseActivity,
    private val cancellable: Boolean = true
): BottomSheetDialogFragment(), CoroutineScope{

    companion object{
        const val MAX_BOTTOM_SHEET_HEIGHT_PERCENTILE = .6f
    }

    private var job: Job? = null

    override val coroutineContext: CoroutineContext
        get() = job?: Job().also{
            App.log("AsyncApiCall: ApiLifecycle: initJob: ${this.javaClass}")
            job = it
        }

    protected fun cancelJob(){
        App.log("AsyncApiCall: ApiLifecycle: cancelJob: ${this.javaClass}")
        job?.cancel()
        job = null
    }

    override fun getTheme() = R.style.CustomBottomSheetDialogTheme

    private var bottomSheetMain: View? = null
    private lateinit var bottomSheetParent: ViewGroup
    private var bottomSheetBehavior: BottomSheetBehavior<View>? = null
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return (CustomResources.inflateLayout(LayoutInflater.from(a), R.layout.fragment_bottomsheet_base_item, null) as ViewGroup).also {
            bottomSheetParent = it.findViewById(R.id.baseLayout)
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val bottomSheetDialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
        bottomSheetDialog.setOnShowListener { dialog ->
            val d = dialog as BottomSheetDialog
            bottomSheetMain = d.findViewById<View>(R.id.design_bottom_sheet) as FrameLayout
            bottomSheetMain?.let { bottomSheet->
                bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
                bottomSheetBehavior?.apply {
                    state = BottomSheetBehavior.STATE_EXPANDED
                    skipCollapsed = true
                    isHideable = true
                }
                isCancelable = cancellable
            }
        }
        return bottomSheetDialog
    }

    open fun refreshLayout(){
        bottomSheetMain?.let { v->
            v.parent.requestLayout()
            v.requestLayout()
            v.invalidate()
        }
    }

    protected fun setTitle(content: ViewGroup){
        bottomSheetParent.findViewById<LinearLayout>(R.id.dialog_title_content).also {
            it.removeAllViews()
            it.addView(content)
        }
    }

    protected fun setContent(content: ViewGroup){
        bottomSheetParent.findViewById<LinearLayout>(R.id.dialog_content).also {
            it.removeAllViews()
            it.addView(content)
        }
    }

    protected fun setButtons(content: ViewGroup){
        bottomSheetParent.findViewById<LinearLayout>(R.id.buttonLayout).also {
            it.removeAllViews()
            it.addView(content)
        }
    }

    open var isScrollOnTop = false
    protected fun setScrollableContent(content: ViewGroup){
        (CustomResources.inflateLayout(LayoutInflater.from(a), R.layout.dynamic_height_scrollview, null) as ViewGroup).also {
            it.findViewById<ScrollViewWithMaxHeight>(R.id.scrollParent).also { sv->
                sv.setMaxHeight(getScrollViewHeight())
                sv.setOnDynamicHeightChangeListener {}
                sv.viewTreeObserver.addOnScrollChangedListener {
                    isScrollOnTop = sv.scrollY == 0
                }
            }
            it.findViewById<LinearLayout>(R.id.scrollContainer).also { container->
                container.addView(content)
            }
            setContent(it)
        }
    }

    private fun getScrollViewHeight(): Int{
        val screenHeight = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val windowMetrics: WindowMetrics = a.windowManager.currentWindowMetrics
            val insets: Insets = windowMetrics.windowInsets
                .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
            windowMetrics.bounds.height() - insets.left - insets.right
        } else {
            val displayMetrics = DisplayMetrics()
            a.windowManager.defaultDisplay.getMetrics(displayMetrics)
            displayMetrics.heightPixels
        }

        val heightMax = (screenHeight* MAX_BOTTOM_SHEET_HEIGHT_PERCENTILE).toInt()
        App.log("FragmentBottomsheet: screenHeight: $screenHeight, 60%: $heightMax")
        return heightMax
    }

    fun setBottomSheetState(state: Int){
        bottomSheetBehavior?.state = state
    }

    open fun onBottomSheetClosed(){
        cancelJob()
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        onBottomSheetClosed()
    }

    open fun onBackPressed(){
        App.log("FragmentBottomsheet: onBackPressed")
    }
}
martin1337
  • 2,384
  • 6
  • 38
  • 85

0 Answers0