material-components / material-components-android

Modular and customizable Material Design UI components for Android
Apache License 2.0
16.28k stars 3.06k forks source link

[RangeSlider] Knobs/thumbs stays always visible if pulled down inside a SwipeRefreshLayout #2152

Open nordfalk opened 3 years ago

nordfalk commented 3 years ago

Description: If I drag down while adjustring the knobs on a RangeSlider which is inside a androidx.swiperefreshlayout.widget.SwipeRefreshLayout , then the knobs stays there forever.

See this video https://youtu.be/mtM-h6Rz78M

Expected behavior: Knobs should disappear when I drag down. Instead the SwipeRefreshLayout appears and the knobs stays forever

Source code:

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
  android:id="@+id/swipeRefresh"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:orientation="vertical">

        <com.google.android.material.slider.RangeSlider
            android:id="@+id/rangeSlider"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:valueFrom="0"
            android:valueTo="8" />

Setting

   android:enabled="false"

in @+id/swipeRefresh makes the problem go away (but also the swipe to refresh ability)

Android API version: It has been verified on API 23 and API 30

Material Library version: It has been verified on com.google.android.material:material:1.3.0 and com.google.android.material:material:1.2.1

Device: Many physical and virtual devices

nordfalk commented 3 years ago

Here is a workaround that simply disables the swipeRefresh while using the slider:

    rangeSlider.addOnSliderTouchListener( object : RangeSlider.OnSliderTouchListener{
        override fun onStartTrackingTouch(slider: RangeSlider) {
            swipeRefresh.isEnabled = false
        }

        override fun onStopTrackingTouch(slider: RangeSlider) {
            swipeRefresh.isEnabled = true
        }
    })
drchen commented 3 years ago

The issue seems caused by SwipeRefreshLayout.

What JetPack version are you using?

nordfalk commented 3 years ago

I am using swiperefreshlayout-1.0.0 and material-1.2.1.

Here is a better workaround:

private var rangeSliderIsInUse = false

...

    swipeRefresh.setOnChildScrollUpCallback { parent, child ->
        val blockSwipeToRefresh = amountRangeSliderIsInUse || layoutManager.findFirstCompletelyVisibleItemPosition() > 0
        blockSwipeToRefresh // return true if "swipe to refresh" should be blocked, becaurse it is possible to scroll up, or range sliders are in use right now
    }

    rangeSlider.addOnSliderTouchListener(object : RangeSlider.OnSliderTouchListener {
        override fun onStartTrackingTouch(slider: RangeSlider) {
            rangeSliderIsInUse = true
        }

        override fun onStopTrackingTouch(slider: RangeSlider) {
            rangeSliderIsInUse = false
        }
    })