在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 } }