0
0
mirror of https://github.com/Ishan09811/pine.git synced 2025-04-24 08:55:10 +00:00

Implement Material SeekBarPreference (#50)

This commit is contained in:
Ishan09811 2025-01-04 17:34:36 +05:30 committed by GitHub
parent 9a72c247fc
commit 0a710eaf10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 146 additions and 12 deletions

View File

@ -0,0 +1,102 @@
package emu.skyline.preference
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.preference.DialogPreference
import androidx.preference.Preference
import emu.skyline.R
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.slider.Slider
import com.google.android.material.textview.MaterialTextView
class SeekBarPreference(context: Context, attrs: AttributeSet) : DialogPreference(context, attrs) {
private var currentValue: Number = 0 // Use Number to hold either Int or Float
private var minValue: Number = 0
private var maxValue: Number = 100
private var step: Float = 1f
private var isPercentage: Boolean = false
init {
// Read custom attributes
context.theme.obtainStyledAttributes(attrs, R.styleable.MaterialSeekBarPreference, 0, 0).apply {
try {
isPercentage = getBoolean(R.styleable.MaterialSeekBarPreference_isPercentage, false)
val attrMinValue = getString(R.styleable.MaterialSeekBarPreference_minValue)?.toIntOrNull() ?: 0
val attrMaxValue = getString(R.styleable.MaterialSeekBarPreference_maxValue)?.toIntOrNull() ?: 100
minValue = attrMinValue
maxValue = attrMaxValue
} finally {
recycle()
}
}
}
override fun onClick() { showMaterialDialog() }
private fun showMaterialDialog() {
val dialogView = LayoutInflater.from(context).inflate(R.layout.preference_dialog_seekbar, null)
val slider = dialogView.findViewById<Slider>(R.id.seekBar)
val valueText = dialogView.findViewById<MaterialTextView>(R.id.value)
// Configure slider
slider.valueFrom = if (isPercentage) minValue.toFloat() else minValue.toInt().toFloat()
slider.valueTo = if (isPercentage) maxValue.toFloat() else maxValue.toInt().toFloat()
slider.stepSize = step
slider.value = if (isPercentage) currentValue.toFloat() else currentValue.toInt().toFloat()
// Display initial value
updateValueText(valueText, slider.value)
slider.addOnChangeListener { _, value, _ ->
updateValueText(valueText, value)
currentValue = if (isPercentage) value else value.toInt()
}
// Build and show the MaterialAlertDialog
MaterialAlertDialogBuilder(context)
.setTitle(title)
.setView(dialogView)
.setPositiveButton(android.R.string.ok) { _, _ ->
if (isPercentage) {
persistFloat(currentValue.toFloat())
} else {
persistInt(currentValue.toInt())
}
updateSummary()
callChangeListener(currentValue)
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
slider.value = summary.toString().replace("%", "").toInt().toFloat()
}
.show()
}
private fun updateValueText(valueText: MaterialTextView, value: Float) {
valueText.text = if (isPercentage) {
"${value.toInt()}%"
} else {
value.toInt().toString()
}
}
private fun updateSummary() {
summary = if (isPercentage) {
"${currentValue.toFloat().toInt()}%"
} else {
currentValue.toInt().toString()
}
}
override fun onSetInitialValue(defaultValue: Any?) {
currentValue = if (isPercentage) {
getPersistedFloat((defaultValue as? Float) ?: minValue.toFloat()).toFloat()
} else {
getPersistedInt((defaultValue as? Int) ?: minValue.toInt())
}
updateSummary()
}
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/value"
style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="@dimen/cornerRadiusMedium"
android:layout_marginTop="@dimen/cornerRadiusMedium" />
<com.google.android.material.slider.Slider
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/value"
android:layout_marginBottom="@dimen/cornerRadiusMedium"
android:layout_marginLeft="@dimen/cornerRadiusMedium"
android:layout_marginRight="@dimen/cornerRadiusMedium" />
</RelativeLayout>

View File

@ -32,4 +32,9 @@
<!-- Index of the controller the preference corresponds to -->
<attr name="index" format="integer" />
</declare-styleable>
<declare-styleable name="MaterialSeekBarPreference">
<attr name="isPercentage" format="boolean" />
<attr name="minValue" format="string" />
<attr name="maxValue" format="string" />
</declare-styleable>
</resources>

View File

@ -147,22 +147,22 @@
app:key="vsync_mode"
app:title="@string/vsync_mode"
app:useSimpleSummaryProvider="true"/>
<SeekBarPreference
<emu.skyline.preference.SeekBarPreference
android:defaultValue="4"
android:max="6"
android:min="1"
android:summary="@string/executor_slot_count_scale_desc"
app:key="executor_slot_count_scale"
app:showSeekBarValue="true"
app:title="@string/executor_slot_count_scale" />
<SeekBarPreference
android:key="executor_slot_count_scale"
android:title="@string/executor_slot_count_scale"
app:maxValue="6"
app:minValue="1"
app:isPercentage="false" />
<emu.skyline.preference.SeekBarPreference
android:defaultValue="256"
android:max="1024"
android:min="0"
android:summary="@string/executor_flush_threshold_desc"
app:key="executor_flush_threshold"
app:showSeekBarValue="true"
app:title="@string/executor_flush_threshold" />
android:key="executor_flush_threshold"
android:title="@string/executor_flush_threshold"
app:maxValue="1024"
app:minValue="0"
app:isPercentage="false" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:summary="@string/use_direct_memory_import_desc"