Avoid accidental tap/touch in a Jetpack Compose Slider which is placed inside in a scrollable column

Viewed 629

I have a Slider which is placed inside a Column which is scrollable. When i scroll through the components sometimes accidentally slider value changes because of accidental touches. How can i avoid this?

  1. Should i be disable taps on slider? If yes how can i do it?

  2. Is there any alternate like Nested scroll instead of Column which can prevent this from happening?

    @Composable
    fun ColumnScope.FilterRange(
     title: String,
     range: ClosedFloatingPointRange<Float>,
     rangeText: String,
     valueRange: ClosedFloatingPointRange<Float>,
     onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,
    ) {
    Spacer(modifier = Modifier.height(Size_Regular))
    
     Text(
        text = title,
        style = MaterialTheme.typography.h6
     )
    
     Spacer(modifier = Modifier.height(Size_X_Small))
    
     Text(
        text = rangeText,
        style = MaterialTheme.typography.subtitle1
    )
    
     RangeSlider(
        modifier = Modifier.fillMaxWidth(),
        values = range,
        valueRange = valueRange,
        onValueChange = {
            onValueChange(it)
        })
    
     Spacer(modifier = Modifier.height(Size_Small))
    
     Divider(thickness = DividerSize)
    }
    
    
1 Answers

I would disable the RangeSlider and only enable it when you tap on it. You disable it by tapping anywhere else within the Column. This is a similar behavior used to mimic losing focus. Here's an example:

class MainActivity : ComponentActivity() {
    @ExperimentalMaterialApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        startActivity(intent)

        setContent {

            var rangeEndabled by remember { mutableStateOf(false)}.apply { this.value }
            var sliderPosition by remember { mutableStateOf(0f..100f) }
            Text(text = sliderPosition.toString())

            Column(modifier = Modifier
                .fillMaxSize()
                .verticalScroll(rememberScrollState())
                .pointerInput(Unit) {
                    detectTapGestures(
                        onTap = {
                            rangeEndabled = false
                        }
                    )
                }) {
                
                repeat(30) {
                    Text(it.toString())
                }

                RangeSlider(
                    enabled = rangeEndabled,
                    values = sliderPosition,
                    onValueChange = { sliderPosition = it },
                    valueRange = 0f..100f,
                    onValueChangeFinished = {
                        // launch some business logic update with the state you hold
                        // viewModel.updateSelectedSliderValue(sliderPosition)
                    },
                    modifier = Modifier.pointerInput(Unit) {
                        detectTapGestures(
                            onTap = {
                                rangeEndabled = true
                            }
                        )
                    }
                )

                repeat(30) {
                    Text(it.toString())
                }
            }

        }
    }
}
Related