skydoves / PowerSpinner

🌀 A lightweight dropdown popup spinner, fully customizable with an arrow and animations for Android.
Apache License 2.0
1.2k stars 114 forks source link

setOnSpinnerOutsideTouchListener does not fire #11

Closed davischung closed 4 years ago

davischung commented 4 years ago

Please complete the following information:

Describe the Bug:

Im using Kotlin with PowerSpinner, setting the onSpinnerOutsideTouchListener using setOnSpinnerOutsideTouchListener { view, motionEvent -> } does not get fired while touching outside spinner when the spinner is open

Expected Behavior:

Expect to get event fired when touching outside spinner when the spinner is open, so that I could close the spinner. It would be good if the spinner could be closed when user click the physical back button.

skydoves commented 4 years ago

@davischung Hi, I checked it and It will be fixed in the next release. Thank you for your issue :)

mariooooo commented 4 years ago

it would be great if you fixed it

skydoves commented 4 years ago

If there is no more issue, the fixed version will be released today. Thank you :)

skydoves commented 4 years ago

@davischung @mariooooo It's released a new version 1.0.6. Thank you for your issue :)

davischung commented 4 years ago

@skydoves @mariooooo Verified it fired on 1.0.6, good job.

mariooooo commented 4 years ago

@skydoves I don’t know, but it doesn’t work for me, maybe I'm doing something wrong spinner.setOnSpinnerOutsideTouchListener { view, motionEvent -> println("outside touch") spinner.dismiss() } youtube

Elytum commented 4 years ago

Hi ! Same here, 1.0.6 didn't fix the issue, still having to resort to a dirty use of "dispatchTouchEvent" in the activity. Will try to understand how to fix it later if needed, anyway thanks for the library !

mariooooo commented 4 years ago

@skydoves what about this problem?

skydoves commented 4 years ago

@mariooooo Hi, did you build using the demo project? It would not be fired if the spinnerVIew is not focusable because of other editText.

Add the below code to the MainActivity.

spinnerView.spinnerOutsideTouchListener = object : OnSpinnerOutsideTouchListener {
      override fun onSpinnerOutsideTouch(view: View, event: MotionEvent) {
        Toast.makeText(baseContext, "touched outside", Toast.LENGTH_SHORT).show()
        spinnerView.dismiss()
      }
    }
davischung commented 4 years ago

@skydoves There is a side-issue produced by this setOnSpinnerItemSelectedListener fix. If you click on the PowerSpinnerView it will shows the dropdown, clicking one more time should dismiss the dropdown.

The intention to add a setOnSpinnerOutsideTouchListener is to dismiss the dropdown while click was being detected outside the dropdown, to implement is to call dismiss() in the callback function. However, by adding a setOnSpinnerOutsideTouchListener, clicking on the PowerSpinnerView when dropdown is showing will fire showOrDismiss twice if dismiss() is being called within setOnSpinnerOutsideTouchListener {}, resulting unable to dismiss the PowerSpinnerView dropdown by clicking it again.

One quick fix on my side is to add some handling like below to override the onClickListener:

var dismissTime: Date? = null
binding.spinnerRegionCode.apply {
    ...
    setOnSpinnerOutsideTouchListener { _, _ ->
        dismissTime = Date()
        binding.spinnerRegionCode.dismiss()
    }
}
binding.spinnerRegionCode.setOnClickListener {
    if (Date().time - (dismissTime?.time ?: 0) > 200) {
        binding.spinnerRegionCode.showOrDismiss()
    }
    dismissTime = null
}

See if you could handle it within the library. Thanks.

ShivamDev31 commented 4 years ago

Facing the same issue as @davischung

skydoves commented 4 years ago

It is released on the new version 1.0.8! And you can set the new attribute debounce_duration.