12 ответов:
обновление https://stackoverflow.com/a/36373569/1835650
getConstantState () работает не очень хорошо
есть еще один способ сравнить:mRememberPwd.getDrawable().getConstantState().equals (getResources().getDrawable(R.drawable.login_checked).getConstantState());
mRemeberPwdэтоImageViewв этом примере. Если вы используетеTextViewиспользуйте .
опираясь на
getConstantState()только это может привести к ложноотрицательными.подход, который я принял, заключается в том, чтобы попытаться сравнить константное состояние в первом случае, но вернуться к сравнению растровых изображений, если эта проверка не выполняется.
Это должно работать во всех случаях (включая изображения, которые не ресурсов), но обратите внимание, что это голодная память.
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 - e.g. 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; }
мой вопрос был просто для сравнения двух чертежей,я попытался, но не смог получить какой-либо метод, который непосредственно сравнивает два чертежа, однако для моего решения я изменил drawable на bitmap, а затем сравнил два растровых изображения, и это работает.
Bitmap bitmap = ((BitmapDrawable)fDraw).getBitmap(); Bitmap bitmap2 = ((BitmapDrawable)sDraw).getBitmap(); if(bitmap == bitmap2) { //Code blcok }
решение для Android 5:
if(image.getDrawable().getConstantState().equals(image.getContext().getDrawable(R.drawable.something).getConstantState()))
для SDK 21+
это работает в SDK -21
mRememberPwd.getDrawable().getConstantState().equals (getResources().getDrawable(R.drawable.login_checked).getConstantState())для SDK + 21 android 5. установите drawable id в imageview с тегом
img.setTag(R.drawable.xxx);и сравнить вот так
if ((Integer) img.getTag() == R.drawable.xxx) { ....your code }это решение для тех, кто хочет сравнить
drawableкодimageviewс идентификаторомdrawable.xxx.
возможно, попробуйте это таким образом:
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 и возвращает boolean. В этом методе вы можете конвертировать 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; }
хорошо, я думаю, что нашел окончательное решение для этого. Из-за AppCompat и друзей, drawable при условии, иногда раздувается в разных формах, так что это не достаточно, чтобы сделать
getResources().getBitmap(R.drawable.my_awesome_drawable).Итак, для того, чтобы получить выигрышного экземпляр того же типа и формы, предусмотренных зрения можно сделать так:
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); } }это полезно при выполнении тестов. Однако я бы не рекомендовал делать это в производстве. Если вам нужно, дополнительного кэширования желательно избежать слишком много размышлений.
для тестов Expresso вы можете использовать это довольно красиво:
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); } } } }
getDrawable (int) Теперь не рекомендуется. Используйте getDrawable (контекст,R. drawable.yourimageid)
Для Сравнения Двух Фонов
Boolean Condition1=v.getBackground().getConstantState().equals( ContextCompat.getDrawable(getApplicationContext(),R.drawable.***).getConstantState());
Я уже отвечал на подобную тему здесь:получить идентификатор drawable в ImageView. Этот подход основан на тегировании представления с указанным идентификатором ресурса в пользовательском
LayoutInflater. Весь процесс автоматизирован простой библиотекой TagView.в результате вы можете сравнить два чертежа только по их идентификаторам:
TagViewUtils.getTag(view, ViewTag.VIEW_BACKGROUND.id) == R.drawable.twt_hover
Если вы хотите напрямую сравнить два 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 } }
Comments