简体   繁体   中英

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

I have two MaterialButton s 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.

在此输入图像描述

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

在此输入图像描述

Photo of what currently happens in Android Lollipop.

在此输入图像描述

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()
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM