Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 043d2389 authored by Edgar Wang's avatar Edgar Wang
Browse files

[Expressive design] SegmentedButtonPreference

Apply button data during onBindViewHolder

Since it is possible for the number of buttons to change after onBindViewHolder,
store the data and apply it during the next onBindViewHolder call.
Also, hide the unselected button texts.

Bug: 399316980
Test: manual
Flag: EXEMPT bug fix
Change-Id: I48a7b70fbc3f13d41ccd5c64608e45466fd89bad
parent 9545062d
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -20,10 +20,12 @@
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="@dimen/settingslib_expressive_space_extrasmall4"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">

    <com.google.android.material.button.MaterialButtonToggleGroup
        android:theme="@style/Theme.Material3.DynamicColors.DayNight"
        android:id="@+id/button_group"
        style="@style/Widget.Material3Expressive.MaterialButtonGroup.Connected"
        android:layout_width="match_parent"
@@ -36,24 +38,28 @@
            android:layout_weight="1"
            app:iconPadding="0dp"
            app:iconGravity="textStart"
            android:visibility="gone"
            style="@style/SettingsLibButtonStyle.Expressive.Tonal.Large"/>
        <com.google.android.material.button.MaterialButton
            android:id="@+id/button_2"
            android:layout_weight="1"
            app:iconPadding="0dp"
            app:iconGravity="textStart"
            android:visibility="gone"
            style="@style/SettingsLibButtonStyle.Expressive.Tonal.Large"/>
        <com.google.android.material.button.MaterialButton
            android:id="@+id/button_3"
            android:layout_weight="1"
            app:iconPadding="0dp"
            app:iconGravity="textStart"
            android:visibility="gone"
            style="@style/SettingsLibButtonStyle.Expressive.Tonal.Large"/>
        <com.google.android.material.button.MaterialButton
            android:id="@+id/button_4"
            android:layout_weight="1"
            app:iconPadding="0dp"
            app:iconGravity="textStart"
            android:visibility="gone"
            style="@style/SettingsLibButtonStyle.Expressive.Tonal.Large"/>
    </com.google.android.material.button.MaterialButtonToggleGroup>

@@ -72,7 +78,8 @@
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textAppearance="@style/TextAppearance.SettingsLib.TitleSmall.Emphasized"
            android:textColor="@color/settingslib_materialColorOnSurface" />
            android:textColor="@color/settingslib_materialColorOnSurface"
            android:visibility="gone" />

        <TextView
            android:id="@+id/button_2_text"
@@ -81,7 +88,8 @@
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textAppearance="@style/TextAppearance.SettingsLib.TitleSmall.Emphasized"
            android:textColor="@color/settingslib_materialColorOnSurface" />
            android:textColor="@color/settingslib_materialColorOnSurface"
            android:visibility="gone" />

        <TextView
            android:id="@+id/button_3_text"
@@ -90,7 +98,8 @@
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textAppearance="@style/TextAppearance.SettingsLib.TitleSmall.Emphasized"
            android:textColor="@color/settingslib_materialColorOnSurface" />
            android:textColor="@color/settingslib_materialColorOnSurface"
            android:visibility="gone" />

        <TextView
            android:id="@+id/button_4_text"
@@ -99,6 +108,7 @@
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textAppearance="@style/TextAppearance.SettingsLib.TitleSmall.Emphasized"
            android:textColor="@color/settingslib_materialColorOnSurface" />
            android:textColor="@color/settingslib_materialColorOnSurface"
            android:visibility="gone" />
    </LinearLayout>
</LinearLayout>
 No newline at end of file
+80 −13
Original line number Diff line number Diff line
@@ -38,6 +38,11 @@ class SegmentedButtonPreference @JvmOverloads constructor(
    private var buttonLabels: MutableList<TextView> = mutableListOf()
    private var buttonCheckedListener: MaterialButtonToggleGroup.OnButtonCheckedListener? = null

    // Data to be applied during onBindViewHolder
    private val buttonSetupData = mutableListOf<Triple<Int, String, Int>>() // (index, text, icon)
    private val buttonVisibilityData = mutableListOf<Pair<Int, Boolean>>() // (index, visibility)
    private val buttonEnableData = mutableListOf<Pair<Int, Boolean>>() // (index, enable)

    init {
        layoutResource = R.layout.settingslib_expressive_preference_segmentedbutton
    }
@@ -52,37 +57,99 @@ class SegmentedButtonPreference @JvmOverloads constructor(
        buttonLabels.add(holder.findViewById(R.id.button_2_text) as TextView)
        buttonLabels.add(holder.findViewById(R.id.button_3_text) as TextView)
        buttonLabels.add(holder.findViewById(R.id.button_4_text) as TextView)

        // Apply stored data
        applyButtonSetupData()
        applyButtonVisibilityData()
        applyButtonEnableData()
        buttonGroup?.apply {
            clearOnButtonCheckedListeners()
            buttonCheckedListener?.let { listener ->
                addOnButtonCheckedListener(listener)
            }
        }
    }

    fun setupButton(index: Int, text: String, @DrawableRes icon: Int) {
        if (index in 0 until buttonLabels.size) {
            (buttonGroup?.getChildAt(index) as? MaterialButton)?.setIconResource(icon)
            buttonLabels[index].text = text
    fun setUpButton(index: Int, text: String, @DrawableRes icon: Int) {
        if (buttonGroup == null) {
            // Store data for later application
            buttonSetupData.add(Triple(index, text, icon))
        } else {
            // Apply data
            applyButtonSetupData(index, text, icon)
        }
    }

    fun setButtonVisibility(index: Int, visible: Boolean) {
        if (index in 0 until buttonLabels.size) {
            (buttonGroup?.getChildAt(index) as? MaterialButton)?.visibility =
                if (visible) VISIBLE else GONE

            buttonLabels[index].visibility = if (visible) VISIBLE else GONE
        if (buttonGroup == null) {
            // Store data for later application
            buttonVisibilityData.add(Pair(index, visible))
        } else {
            // Apply data
            applyButtonVisibilityData(index, visible)
        }
    }

    fun setButtonEnabled(index: Int, enabled: Boolean) {
        if (index in 0 until buttonLabels.size) {
            (buttonGroup?.getChildAt(index) as? MaterialButton)?.isEnabled = enabled
        if (buttonGroup == null) {
            // Store data for later application
            buttonEnableData.add(Pair(index, enabled))
        } else {
            // Apply data
            applyButtonEnableData(index, enabled)
        }
    }

    fun setOnButtonClickListener(listener: MaterialButtonToggleGroup.OnButtonCheckedListener) {
        buttonCheckedListener = listener
        buttonGroup?.addOnButtonCheckedListener (listener)
        notifyChanged()
    }

    fun removeOnButtonClickListener() {
        buttonCheckedListener?.let { buttonGroup?.removeOnButtonCheckedListener(it) }
        buttonCheckedListener = null
        notifyChanged()
    }

    private fun applyButtonSetupData() {
        for (config in buttonSetupData) {
            applyButtonSetupData(config.first, config.second, config.third)
        }
        buttonSetupData.clear() // Clear data after applying
    }

    private fun applyButtonVisibilityData() {
        for (config in buttonVisibilityData) {
            applyButtonVisibilityData(config.first, config.second)
        }
        buttonVisibilityData.clear() // Clear data after applying
    }

    private fun applyButtonEnableData() {
        for (config in buttonEnableData) {
            applyButtonEnableData(config.first, config.second)
        }
        buttonEnableData.clear() // Clear data after applying
    }

    private fun applyButtonSetupData(index: Int, text: String, @DrawableRes icon: Int) {
        if (index in 0 until buttonLabels.size) {
            (buttonGroup?.getChildAt(index) as? MaterialButton)?.setIconResource(icon)
            buttonLabels[index].text = text
        }
    }

    private fun applyButtonVisibilityData(index: Int, visible: Boolean) {
        if (index in 0 until buttonLabels.size) {
            (buttonGroup?.getChildAt(index) as? MaterialButton)?.visibility =
                if (visible) VISIBLE else GONE

            buttonLabels[index].visibility = if (visible) VISIBLE else GONE
        }
    }

    private fun applyButtonEnableData(index: Int, enabled: Boolean) {
        if (index in 0 until buttonLabels.size) {
            (buttonGroup?.getChildAt(index) as? MaterialButton)?.isEnabled = enabled
        }
    }
}
 No newline at end of file