在android中比较两个drawable

如何比较两个drawable,我这样做,但没有任何成功

public void MyClick(View view) { Drawable fDraw = view.getBackground(); Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover); if(fDraw.equals(sDraw)) { //Not coming } } 

还有另一种方法可以比较:

 mRememberPwd.getDrawable().getConstantState().equals (getResources().getDrawable(R.drawable.login_checked).getConstantState()); 

在这个例子中, mRemeberPwd是一个ImageView 。 如果您使用的是TextView ,请改用getBackground().getConstantState

仅依赖于getConstantState()会导致错误的否定 。

我采取的方法是在第一次尝试比较ConstantState,但如果检查失败,则回落到位图比较。

这应该适用于所有情况(包括不是资源的图像),但请注意,这是内存饥饿。

 public static boolean areDrawablesIdentical(Drawable drawableA, Drawable drawableB) { Drawable.ConstantState stateA = drawableA.getConstantState(); Drawable.ConstantState stateB = drawableB.getConstantState(); // If the constant state is identical, they are using the same drawable resource. // However, the opposite is not necessarily true. return (stateA != null && stateB != null && stateA.equals(stateB)) || getBitmap(drawableA).sameAs(getBitmap(drawableB)); } public static Bitmap getBitmap(Drawable drawable) { Bitmap result; if (drawable instanceof BitmapDrawable) { result = ((BitmapDrawable) drawable).getBitmap(); } else { int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); // Some drawables have no intrinsic width - eg solid colours. if (width <= 0) { width = 1; } if (height <= 0) { height = 1; } result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(result); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); } return result; } 

我的问题是只比较两个可绘制的,我试过,但不能直接比较两个可绘制的任何方法,但是我的解决scheme,我改变绘制到位图,然后比较两个位图,这是工作。

 Bitmap bitmap = ((BitmapDrawable)fDraw).getBitmap(); Bitmap bitmap2 = ((BitmapDrawable)sDraw).getBitmap(); if(bitmap == bitmap2) { //Code blcok } 

Android 5的解决scheme:

  if(image.getDrawable().getConstantState().equals(image.getContext().getDrawable(R.drawable.something).getConstantState())) 

也许试试这样:

 public void MyClick(View view) { Drawable fDraw = view.getBackground(); Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover); if(fDraw.hashCode() == sDraw.hashCode()) { //Not coming } } 

或者准备一个带有两个可绘制参数并返回布尔值的方法。 在这种方法中,您可以将drawable转换为字节并进行比较,

 public boolean compareDrawable(Drawable d1, Drawable d2){ try{ Bitmap bitmap1 = ((BitmapDrawable)d1).getBitmap(); ByteArrayOutputStream stream1 = new ByteArrayOutputStream(); bitmap1.compress(Bitmap.CompressFormat.JPEG, 100, stream1); stream1.flush(); byte[] bitmapdata1 = stream1.toByteArray(); stream1.close(); Bitmap bitmap2 = ((BitmapDrawable)d2).getBitmap(); ByteArrayOutputStream stream2 = new ByteArrayOutputStream(); bitmap2.compress(Bitmap.CompressFormat.JPEG, 100, stream2); stream2.flush(); byte[] bitmapdata2 = stream2.toByteArray(); stream2.close(); return bitmapdata1.equals(bitmapdata2); } catch (Exception e) { // TODO: handle exception } return false; } 

对于SDK 21+

这在SDK -21中工作

 mRememberPwd.getDrawable().getConstantState().equals (getResources().getDrawable(R.drawable.login_checked).getConstantState()) 

为SDK +21 Android 5.设置可绘制的ID到带有标签的imageview

 img.setTag(R.drawable.xxx); 

和这样比较

 if ((Integer) img.getTag() == R.drawable.xxx) { ....your code } 

这个解决scheme是为了谁比较drawable id的drawable id的imageview

好吧,我想我已经find了最终的解决scheme。 由于AppCompat和朋友,所提供的drawable有时会以不同的forms膨胀,所以仅仅使用getResources().getBitmap(R.drawable.my_awesome_drawable)

因此,为了得到与视图提供的相同types和forms的可绘制实例,可以这样做:

 public static Drawable drawableFrom(View view, @DrawableRes int drawableId) { Context context = view.getContext(); try { View dummyView = view.getClass().getConstructor(Context.class).newInstance(context); dummyView.setBackgroundResource(drawableId); return dummyView.getBackground(); } catch (Exception e) { return ResourcesCompat.getDrawable(context.getResources(), drawableId, null); } } 

这在做testing时很有用。 不过,我不build议在生产中这样做。 如果你需要,额外的caching将是可取的,以避免做太多的反思。

对于Expressotesting,您可以很好地使用它:

 onView(withDrawable(R.drawable.awesome_drawable)) .check(matches(isDisplayed())); 

要么

 onView(withId(R.id.view_id)) .check(matches(withDrawable(R.drawable.awesome_drawable))); 

在你必须声明这个助手类之前:

 public class CustomMatchers { public static Matcher<View> withDrawable(@DrawableRes final int drawableId) { return new DrawableViewMatcher(drawableId); } private static class DrawableViewMatcher extends TypeSafeMatcher<View> { private final int expectedId; private String resourceName; private enum DrawableExtractionPolicy { IMAGE_VIEW { @Override Drawable findDrawable(View view) { return view instanceof ImageView ? ((ImageView) view).getDrawable() : null; } }, TEXT_VIEW_COMPOUND { @Override Drawable findDrawable(View view) { return view instanceof TextView ? findFirstCompoundDrawable((TextView) view) : null; } }, BACKGROUND { @Override Drawable findDrawable(View view) { return view.getBackground(); } }; @Nullable private static Drawable findFirstCompoundDrawable(TextView view) { for (Drawable drawable : view.getCompoundDrawables()) { if (drawable != null) { return drawable; } } return null; } abstract Drawable findDrawable(View view); } private DrawableViewMatcher(@DrawableRes int expectedId) { this.expectedId = expectedId; } @Override protected boolean matchesSafely(View view) { resourceName = resources(view).getResourceName(expectedId); return haveSameState(actualDrawable(view), expectedDrawable(view)); } private boolean haveSameState(Drawable actual, Drawable expected) { return actual != null && expected != null && areEqual(expected.getConstantState(), actual.getConstantState()); } private Drawable actualDrawable(View view) { for (DrawableExtractionPolicy policy : DrawableExtractionPolicy.values()) { Drawable drawable = policy.findDrawable(view); if (drawable != null) { return drawable; } } return null; } private boolean areEqual(Object first, Object second) { return first == null ? second == null : first.equals(second); } private Drawable expectedDrawable(View view) { return drawableFrom(view, expectedId); } private static Drawable drawableFrom(View view, @DrawableRes int drawableId) { Context context = view.getContext(); try { View dummyView = view.getClass().getConstructor(Context.class).newInstance(context); dummyView.setBackgroundResource(drawableId); return dummyView.getBackground(); } catch (Exception e) { return ResourcesCompat.getDrawable(context.getResources(), drawableId, null); } } @NonNull private Resources resources(View view) { return view.getContext().getResources(); } @Override public void describeTo(Description description) { description.appendText("with drawable from resource id: "); description.appendValue(expectedId); if (resourceName != null) { description.appendValueList("[", "", "]", resourceName); } } } } 

使用getTag()和setTag()进行比较

getDrawable(int)现在已被弃用。 使用getDrawable(context,R.drawable.yourimageid)

比较两个背景

 Boolean Condition1=v.getBackground().getConstantState().equals( ContextCompat.getDrawable(getApplicationContext(),R.drawable.***).getConstantState()); 

如果你想直接比较两个drawable然后使用下面的代码

Drawable fDraw = getResources()。getDrawable(R.drawable.twt_hover);

Drawable sDraw = getResources()。getDrawable(R.drawable.twt_hover);

 if (fDraw.getConstantState().equals(sDraw.getConstantState())) { //write your code. } else { //write your code. } 

当你使用equals()方法时,它被用来比较内容。 你应该尝试==比较两个对象。

 public void MyClick(View view) { Drawable fDraw = view.getBackground(); Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover); if( fDraw == sDraw ) { // Coming } }