Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android MaterialButton doesn't change it's color programmatically in android lollipop

I have two MaterialButtons in a LinearLayout and I change their background color and text color depending on some internal state that I switch to when either of them is clicked. It works fine in all android versions above lollipop. The Initial state for them in all Android versions are working correctly the problem when I switch colors in lollipop.

Here is a photo of the initial state.

enter image description here

Photo of the correct color in all android versions above Lollipop.

enter image description here

Photo of what currently happens in Android Lollipop.

enter image description here

I don't know what case that. I tried many different things but not any of them worked.

Here is the XML code of the layout file

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <android.support.design.button.MaterialButton
        android:id="@+id/handymanServicesButton"
        style="@style/View.RoundedMaterialButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/margin_medium"
        android:layout_weight="1"
        android:elevation="16dp"
        android:onClick="@{view::handymanServices}"
        android:text="@{viewModel.isHandymanUser() ? @string/handyman_services_button_label : @string/main_button_label}"
        android:textAllCaps="false"
        android:textSize="@dimen/text_size_small"
        tools:text="@string/handyman_services_button_label" />

    <android.support.design.button.MaterialButton
        android:id="@+id/otherButton"
        style="@style/RoundedMaterialButtonNotSelected"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/margin_medium"
        android:layout_weight="1"
        android:elevation="16dp"
        android:onClick="@{view::other}"
        android:text="@string/other_button_label"
        android:textAllCaps="false"
        android:textSize="@dimen/text_size_small" />

</LinearLayout>

The styles that I applied to the button.

<style name="View.RoundedMaterialButton">
    <item name="android:minHeight">@dimen/buttonHeight</item>
    <item name="android:elevation">@dimen/cardElevation</item>
    <item name="android:gravity">center</item>
    <item name="rippleColor">@color/material_ripple_color</item>
    <item name="cornerRadius">24dp</item>
    <item name="android:textSize">14sp</item>
    <item name="android:textStyle">bold</item>
    <item name="backgroundTint">@color/colorAccent</item>
    <item name="android:textAllCaps">true</item>
    <item name="android:textColor">@android:color/white</item>
    <item name="android:textAppearance">@style/TextAppearance.MaterialComponents.Button</item>
</style>

<style name="RoundedMaterialButtonNotSelected" parent="View.RoundedMaterialButton">
    <item name="backgroundTint">@android:color/white</item>
    <item name="android:textColor">@color/colorAccent</item>
</style>

The code in the fragment that changes the colors.

private fun handymanServicesUi() {
    binding.handymanServicesButton.backgroundTintList =
            ContextCompat.getColorStateList(requireContext(), R.color.colorAccent)
    binding.otherButton.backgroundTintList =
            ContextCompat.getColorStateList(requireContext(), android.R.color.white)

    binding.handymanServicesButton.setTextColor(Color.WHITE)
    binding.otherButton.setTextColor(
            ContextCompat.getColor(requireContext(), R.color.colorAccent))
}

fun handymanServices(@Suppress("UNUSED_PARAMETER") view: View) {
    handymanServicesUi()
    viewModel.switchToHandymanServices()
}

private fun otherUi() {
    binding.handymanServicesButton.backgroundTintList =
            ContextCompat.getColorStateList(requireContext(), android.R.color.white)
    binding.otherButton.backgroundTintList =
            ContextCompat.getColorStateList(requireContext(), R.color.colorAccent)

    binding.handymanServicesButton.setTextColor(
            ContextCompat.getColor(requireContext(), R.color.colorAccent))
    binding.otherButton.setTextColor(Color.WHITE)
}

fun other(@Suppress("UNUSED_PARAMETER") view: View) {
    otherUi()
    viewModel.switchToOthers()
}
like image 445
Ahmed Abdelmeged Avatar asked Jan 01 '23 02:01

Ahmed Abdelmeged


1 Answers

Create color state selectors for the text and the background. For text's color you can do the following:

<!--    under res/colors/handyman_text_color_selector.xml-->

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorAccent" android:state_selected="true" />
    <item android:color="@android:color/white" />
</selector>

Do the same for the 'backgroundTint', say handyman_button_color_selector.xml

Next apply them to the layout and use these colors selectors. (It's preferred to add them to the style)

<android.support.design.button.MaterialButton
    android:id="@+id/handymanServicesButton"
    style="@style/View.RoundedMaterialButton"

    android:textColor="@color/handyman_text_color_selector"
    app:backgroundTint="@color/handyman_button_color_selector" />

Finally in Kotlin, just toggle the two buttons:

binding.handymanServicesButton.isSelected = !isSelected
binding.otherButton.isSelected = isSelected

Please review this issue too, it has a similar problem.

like image 51
amrro Avatar answered Jan 13 '23 10:01

amrro