Trigger slider feedback only at intervals of 5%.

This commit is contained in:
codokie 2024-08-12 09:30:51 +03:00
parent e4abd73151
commit 93ce34ebec
3 changed files with 30 additions and 10 deletions

View File

@ -704,9 +704,10 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
value = IntSetting.MAIN_CONTROL_SCALE.int.toFloat() value = IntSetting.MAIN_CONTROL_SCALE.int.toFloat()
stepSize = 1f stepSize = 1f
addOnChangeListener( addOnChangeListener(
HapticListener.wrapOnChangeListener { _: Slider, progress: Float, _: Boolean -> HapticListener.wrapOnChangeListener({ _: Slider, progress: Float, _: Boolean ->
dialogBinding.inputScaleValue.text = "${(progress.toInt() + 50)}%" dialogBinding.inputScaleValue.text = "${(progress.toInt() + 50)}%"
}) }, value)
)
} }
inputScaleValue.text = inputScaleValue.text =
"${(dialogBinding.inputScaleSlider.value.toInt() + 50)}%" "${(dialogBinding.inputScaleSlider.value.toInt() + 50)}%"
@ -716,9 +717,10 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
value = IntSetting.MAIN_CONTROL_OPACITY.int.toFloat() value = IntSetting.MAIN_CONTROL_OPACITY.int.toFloat()
stepSize = 1f stepSize = 1f
addOnChangeListener( addOnChangeListener(
HapticListener.wrapOnChangeListener { _: Slider, progress: Float, _: Boolean -> HapticListener.wrapOnChangeListener({ _: Slider, progress: Float, _: Boolean ->
inputOpacityValue.text = progress.toInt().toString() + "%" inputOpacityValue.text = progress.toInt().toString() + "%"
}) }, value)
)
} }
inputOpacityValue.text = inputOpacitySlider.value.toInt().toString() + "%" inputOpacityValue.text = inputOpacitySlider.value.toInt().toString() + "%"
} }

View File

@ -262,7 +262,7 @@ class SettingsAdapter(
} }
} }
slider.value = (seekbarProgress / slider.stepSize).roundToInt() * slider.stepSize slider.value = (seekbarProgress / slider.stepSize).roundToInt() * slider.stepSize
slider.addOnChangeListener(HapticListener.wrapOnChangeListener(this)) slider.addOnChangeListener(HapticListener.wrapOnChangeListener(this, slider.value))
dialog = MaterialAlertDialogBuilder(fragmentView.fragmentActivity) dialog = MaterialAlertDialogBuilder(fragmentView.fragmentActivity)
.setTitle(item.name) .setTitle(item.name)

View File

@ -7,7 +7,7 @@ import androidx.core.view.ViewCompat
import com.google.android.material.slider.Slider import com.google.android.material.slider.Slider
/** /**
* Wrapper class that enhances listeners with haptic feedback. * Wrapper object that enhances listeners with haptic feedback.
*/ */
object HapticListener { object HapticListener {
@ -31,15 +31,33 @@ object HapticListener {
/** /**
* Wraps a [Slider.OnChangeListener] with haptic feedback. * Wraps a [Slider.OnChangeListener] with haptic feedback.
* Feedback is provided at intervals of 5% to prevent excessive vibrations.
* *
* @param listener The [Slider.OnChangeListener] to be wrapped. Can be null. * @param listener The [Slider.OnChangeListener] to be wrapped. Can be null.
* @param initialValue The value used to initialize the slider.
* @return A new listener which wraps [listener] with haptic feedback. * @return A new listener which wraps [listener] with haptic feedback.
*/ */
fun wrapOnChangeListener(listener: Slider.OnChangeListener?): Slider.OnChangeListener { fun wrapOnChangeListener(listener: Slider.OnChangeListener?, initialValue: Float): Slider.OnChangeListener {
var previousValue = initialValue
return Slider.OnChangeListener { slider: Slider, value: Float, fromUser: Boolean -> return Slider.OnChangeListener { slider: Slider, value: Float, fromUser: Boolean ->
listener?.onValueChange(slider, value, fromUser) listener?.onValueChange(slider, value, fromUser)
if (fromUser) { if (fromUser) {
ViewCompat.performHapticFeedback(slider, HapticFeedbackConstantsCompat.CLOCK_TICK) val interval = (slider.valueTo - slider.valueFrom) * 0.05f
val previousInterval = kotlin.math.round(previousValue / interval) * interval
val valueChange = kotlin.math.abs(value - previousInterval)
val feedbackConstant = if (value == slider.valueFrom || value == slider.valueTo) {
HapticFeedbackConstantsCompat.CONTEXT_CLICK
} else if (value == previousValue || valueChange >= interval) {
HapticFeedbackConstantsCompat.CLOCK_TICK
} else {
HapticFeedbackConstantsCompat.NO_HAPTICS
}
if (feedbackConstant != HapticFeedbackConstantsCompat.NO_HAPTICS) {
ViewCompat.performHapticFeedback(slider, feedbackConstant)
previousValue = value
}
} else {
previousValue = value
} }
} }
} }