5

I make bottom sheet fragment like this:

val bottomSheet = PictureBottomSheetFragment(fragment)
bottomSheet.isCancelable = true
bottomSheet.setListener(pictureListener)
bottomSheet.show(ac.supportFragmentManager, "PictureBottomSheetFragment")

But its not dismiss when I touch outside. and dismiss or isCancelable not working.

3 Answers3

0

try this

behavior.setState(BottomSheetBehavior.STATE_HIDDEN));
enderkoca
  • 146
  • 9
  • if you couldn't solve your problem, can you try this -> behavior.setState(BottomSheetBehavior.STATE_COLLAPSED) – enderkoca Jan 11 '20 at 17:17
0

You can override method and indicate, for example, in onViewCreated what you need:

class ModalDialogSuccsesDataPatient : ModalDialog() {
   override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
       super.onViewCreated(view, savedInstanceState)
       isCancelable = false //or true
   }
}
Valentin
  • 400
  • 2
  • 11
0

Let's try to design reusable functions to solve this problem and similar ones if the need arises.

We can create extension functions on View that tell whether a point on the screen is contained within the View or not.

fun View.containsPoint(rawX: Int, rawY: Int): Boolean {
    val rect = Rect()
    this.getGlobalVisibleRect(rect)

    return rect.contains(rawX, rawY)
}

fun View.doesNotContainPoint(rawX: Int, rawY: Int) = !containsPoint(rawX, rawY)

Now we can override the dispatchTouchEvent(event: MotionEvent) method of Activity to know where exactly the user clicked on the screen.

private const val SCROLL_THRESHOLD = 10F // To filter out scroll gestures from clicks
    
private var downX = 0F
private var downY = 0F
private var isClick = false

override fun dispatchTouchEvent(event: MotionEvent): Boolean {
    when (event.action and MotionEvent.ACTION_MASK) {
        MotionEvent.ACTION_DOWN -> {
            downX = event.x
            downY = event.y
            isClick = true
        }

        MotionEvent.ACTION_MOVE -> {
            val xThreshCrossed = abs(downX - event.x) > SCROLL_THRESHOLD
            val yThreshCrossed = abs(downY - event.y) > SCROLL_THRESHOLD

            if (isClick and (xThreshCrossed or yThreshCrossed)) {
                isClick = false
            }
        }

        MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
            if (isClick) onScreenClick(event.rawX, event.rawY)
        }

        else -> { }
    }

    return super.dispatchTouchEvent(event)
}

private fun onScreenClick(rawX: Float, rawY: Float) { }

Now, you can simply use the above-defined functions to achieve the required result

private fun onScreenClick(rawX: Float, rawY: Float) {
    if (bottomSheet.doesNotContainPoint(rawX.toInt(), rawY.toInt())) {
        // Handle bottomSheet state changes
    }
}

What more? If you have a BaseActivity which is extended by all your Activities then you can add the click detection code to it. You can make the onScreenClick an protected open method so that it can be overridden by the sub-classes.

protected open fun onScreenClick(rawX: Float, rawY: Float) { }

Usage:

override fun onScreenClick(rawX: Float, rawY: Float) {
    super.onScreenClick(rawX, rawY)
       
    if (bottomSheet.doesNotContainPoint(rawX.toInt(), rawY.toInt())) {
        // Handle bottomSheet state changes
    }
}
Divyanshu Pundir
  • 145
  • 1
  • 1
  • 8