Espresso校验LinearLayout背景色报LayerDrawable无法转ColorDrawable错误求助
错误原因
- 直接强制将
LayerDrawable转为ColorDrawable失败:你为LinearLayout设置的背景是多层叠加的LayerDrawable(通常由layer-list、selector类xml定义生成),不属于ColorDrawable类型,强转直接触发类型转换异常 - 参数类型不匹配:你调用自定义Matcher时传入的是
R.drawable类型的Drawable资源ID,而Matcher中比对逻辑是判断颜色值,二者不匹配
修复方案
方案1:仅校验背景色(兼容LayerDrawable)
修改后的自定义Matcher如下,可自动适配ColorDrawable和LayerDrawable类型的背景:
public static Matcher<View> withBgColor(final int expectedColorRes) { Checks.checkNotNull(expectedColorRes); return new BoundedMatcher<View, LinearLayout>(LinearLayout.class) { @Override public boolean matchesSafely(LinearLayout row) { Drawable background = row.getBackground(); int actualColor; if (background instanceof ColorDrawable) { actualColor = ((ColorDrawable) background).getColor(); } else if (background instanceof LayerDrawable) { // 若目标色值在LayerDrawable的非第0层,可自行调整索引值 Drawable targetLayer = ((LayerDrawable) background).getDrawable(0); if (!(targetLayer instanceof ColorDrawable)) { return false; } actualColor = ((ColorDrawable) targetLayer).getColor(); } else { return false; } int expectedColor = ContextCompat.getColor(row.getContext(), expectedColorRes); return expectedColor == actualColor; } @Override public void describeTo(Description description) { description.appendText("with background color: "); description.appendValue(expectedColorRes); } }; }
调用时需传入颜色资源ID(R.color.xxx):
onView(ViewMatchers.withId(R.id.device_linearLayout)) .check(ViewAssertions.matches(withBgColor(R.color.your_target_color)));
方案2:校验整个背景Drawable
如果你需要直接校验背景是否为指定的Drawable资源,可使用如下Matcher:
public static Matcher<View> withBackgroundDrawable(final int expectedDrawableRes) { Checks.checkNotNull(expectedDrawableRes); return new BoundedMatcher<View, LinearLayout>(LinearLayout.class) { @Override public boolean matchesSafely(LinearLayout row) { Drawable actualBg = row.getBackground(); Drawable expectedBg = ContextCompat.getDrawable(row.getContext(), expectedDrawableRes); if (actualBg == null || expectedBg == null) return false; Bitmap actualBitmap = drawableToBitmap(actualBg); Bitmap expectedBitmap = drawableToBitmap(expectedBg); return actualBitmap.sameAs(expectedBitmap); } private Bitmap drawableToBitmap(Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap( Math.max(drawable.getIntrinsicWidth(), 1), Math.max(drawable.getIntrinsicHeight(), 1), Bitmap.Config.ARGB_8888 ); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } @Override public void describeTo(Description description) { description.appendText("with background drawable: "); description.appendValue(expectedDrawableRes); } }; }
调用时直接传入你当前的Drawable资源ID即可:
onView(ViewMatchers.withId(R.id.device_linearLayout)) .check(ViewAssertions.matches(withBackgroundDrawable(R.drawable.background_transparent_list)));
内容的提问来源于stack exchange,提问作者mehdi dehghani
相关产品推荐
相关产品推荐

