简体   繁体   中英

create a viewMatcher for the background color of a button

I'm trying to write my own viewMatcher testing the background color of my Button

so I'm trying to implement: Testing background color espresso Android

here's my code and how I call it


fun withBackColor(color: Int): Matcher<View?> {
    Checks.checkNotNull(color)
    return object : BoundedMatcher<View?, Button>(Button::class.java) {
        override fun matchesSafely(button: Button): Boolean {
            val col = (button.background as ColorDrawable).color
            return color == col
        }

        override fun describeTo(description: org.hamcrest.Description) {
            description.appendText("with text color: ")
        }
    }
}
onView(withId(R.id.continueBtn)).check(matches(withBackColor(R.color.custom_color_slider_widget_unselected)))

when I run this code I get: java.lang.ClassCastException: android.graphics.drawable.RippleDrawable cannot be cast to android.graphics.drawable.ColorDrawable

This is my button:

<Button
    android:id="@+id/continueBtn"
    style="@style/ButtonGreyStyle"
    android:layout_marginBottom="25dp"
    android:text="@string/btn_continue"
    android:textColor="@color/white"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent" />

The way it's set is in the on create of the fragment even though the button gets created in an activity launched before

continue_btn?.setBackgroundColor(
    ContextCompat.getColor(
        requireActivity(),
        R.color.custom_color_slider_widget_unselected
    )
)

The style property of the color


<color name="custom_color_slider_widget_unselected">#33EBF5F9</color>

I searched google and found this

Cannot be cast to android.graphics.drawable.ColorDrawable

but didn't find any link to something I could be doing wrong

EDIT:

    override fun matchesSafely(button: Button): Boolean {
        val col = button.background
        val state: ConstantState? = col.constantState
        return try {
            val colorField: Field = state?.javaClass!!.getDeclaredField("mColor")
            colorField.isAccessible = true
            val colorState: ColorStateList = colorField.get(state) as ColorStateList
            val rippleColor: Int = colorState.defaultColor
            color == rippleColor
        } catch (e: NoSuchFieldException) {
            e.printStackTrace()
            false
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
            false
        }
    }

I'm now trying to get the color of the RippleDrawable without a cast to ColorDrawable but i get the NoSuchFieldException

Accessing hidden field Landroid/graphics/drawable/RippleDrawable$RippleState;->mColor:Landroid/content/res/ColorStateList; (max-target-r, reflection, denied) 11-16 14:10:21.227 19473 19473 W System.err: java.lang.NoSuchFieldException: No field mColor in class Landroid/graphics/drawable/RippleDrawable$RippleState; (declaration of 'android.graphics.drawable.RippleDrawable$RippleState' appears in /system/framework/framework.jar)

调试图像

调试图像

The problem about not being able to cast the background as colorDrawable was that in my layout xml

<Button
   android:id="@+id/continueBtn"
   style="@style/ButtonGreyStyle"
   android:layout_marginBottom="25dp"
   android:text="@string/btn_continue"
   android:textColor="@color/white"
   app:layout_constraintBottom_toBottomOf="parent"
   app:layout_constraintEnd_toEndOf="parent"
   app:layout_constraintStart_toStartOf="parent" />

the background element was not defined and even though it was modified in my kotlin adding to the layout

android:background="@color/custom_color_slider_widget_unselected"

made me able to cast in colorDrawable and then modifying the matcher to get the hex of color like so:

fun withBackColor(color: Int): Matcher<View?> {
Checks.checkNotNull(color)
return object : BoundedMatcher<View?, Button>(Button::class.java) {
    override fun matchesSafely(button: Button): Boolean {
        val backColor = (button.background as ColorDrawable).color
        val idColor = ContextCompat.getColor(button.context, color)
        val backHexColor = String.format("#%06X", 0xFFFFFF and backColor)
        val idHexColor = String.format("#%06X", 0xFFFFFF and idColor)
        return backHexColor == idHexColor
    }

    override fun describeTo(description: org.hamcrest.Description) {
        description.appendText("background color wrong")
    }
}

and I can now test for the color of the background of a button

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