Cómo comparar dos dibujables, lo hago así pero no tengo ningún éxito
public void MyClick(View view)
{
Drawable fDraw = view.getBackground();
Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover);
if(fDraw.equals(sDraw))
{
//Not coming
}
}
Respuestas:
Actualizar https://stackoverflow.com/a/36373569/1835650
getConstantState () no funciona bien
Hay otra forma de comparar:mRememberPwd.getDrawable().getConstantState().equals (getResources().getDrawable(R.drawable.login_checked).getConstantState());
mRemeberPwd
es unImageView
en este ejemplo. Si está usando unTextView
, usegetBackground().getConstantState
en su lugar.fuente
Depender
getConstantState()
solo puede resultar en falsos negativos .El enfoque que he adoptado es intentar comparar ConstantState en primera instancia, pero recurrir a una comparación de mapa de bits si esa comprobación falla.
Esto debería funcionar en todos los casos (incluidas las imágenes que no son recursos) pero tenga en cuenta que consume mucha memoria.
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; }
fuente
getConstantState()
comparaciónsetBounds
ydraw
en una copia en lugar del original stackoverflow.com/a/25462223/1916449Mi pregunta era simplemente comparar dos elementos de diseño, lo intenté, pero no pude obtener ningún método que compare directamente dos elementos de diseño, sin embargo, para mi solución, cambié el elemento de diseño a mapa de bits y luego comparé dos mapas de bits y eso está funcionando.
Bitmap bitmap = ((BitmapDrawable)fDraw).getBitmap(); Bitmap bitmap2 = ((BitmapDrawable)sDraw).getBitmap(); if(bitmap == bitmap2) { //Code blcok }
fuente
para SDK 21+
esto funciona en SDK -21
mRememberPwd.getDrawable().getConstantState().equals (getResources().getDrawable(R.drawable.login_checked).getConstantState())
para SDK +21 android 5. establezca la identificación dibujable en imageview con etiqueta
img.setTag(R.drawable.xxx);
y comparar así
if ((Integer) img.getTag() == R.drawable.xxx) { ....your code }
esta solución es para quien quiera comparar
drawable
id deimageview
con id dedrawable.xxx
.fuente
La solución para Android 5:
if(image.getDrawable().getConstantState().equals(image.getContext().getDrawable(R.drawable.something).getConstantState()))
fuente
getDrawable (int) ahora está obsoleto. Utilice getDrawable (contexto, R.drawable.yourimageid)
Comparar dos fondos
Boolean Condition1=v.getBackground().getConstantState().equals( ContextCompat.getDrawable(getApplicationContext(),R.drawable.***).getConstantState());
fuente
context.getResources().getDrawable(R.drawable.***)
en Android 6+ pero no en Android 5. Con este pequeño cambio, puedo comparar los dibujables de fondo en todas las versiones de Android sin problemas.quizás intentarlo de esta manera:
public void MyClick(View view) { Drawable fDraw = view.getBackground(); Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover); if(fDraw.hashCode() == sDraw.hashCode()) { //Not coming } }
o preparar un método que tome dos argumentos dibujables y devuelva booleanos. En ese método, puede convertir dibujable en bytes y comparar,
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; }
fuente
e.g R.drawable.abc
ambos parámetros?Ok, creo que he encontrado la solución definitiva para esto. Gracias a AppCompat y sus amigos, el dibujante proporcionado a veces se infla en diferentes formas, por lo que no es suficiente
getResources().getBitmap(R.drawable.my_awesome_drawable)
.Entonces, para obtener una instancia dibujable del mismo tipo y forma que proporciona la vista, uno puede hacer esto:
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); } }
Esto es útil al realizar pruebas. Sin embargo, no recomendaría hacer esto en producción. Si es necesario, sería deseable almacenamiento en caché adicional para evitar hacer demasiada reflexión.
Para las pruebas de Expresso, puede usar esto bastante bien:
onView(withDrawable(R.drawable.awesome_drawable)) .check(matches(isDisplayed()));
o
onView(withId(R.id.view_id)) .check(matches(withDrawable(R.drawable.awesome_drawable)));
Antes tendrás que declarar esta clase auxiliar:
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); } } } }
fuente
fuente
Ya respondí sobre un tema similar aquí: Obtenga el ID de un elemento de diseño en ImageView . El enfoque se basa en etiquetar una vista con un ID de recurso específico en el archivo personalizado
LayoutInflater
. Todo el proceso está automatizado por una simple biblioteca TagView .Como resultado, puede comparar dos elementos de diseño solo por sus identificadores:
fuente
Ampliando la respuesta de @vaughandroid, el siguiente Matcher funciona para un Vector Drawable que está teñido. Debe proporcionar el tinte que se utilizó para Drawable.
public static Matcher<View> compareVectorDrawables(final int imageId, final int tintId) { return new TypeSafeMatcher<View>() { @Override protected boolean matchesSafely(View target) { if (!(target instanceof ImageView)) { return false; } ImageView imageView = (ImageView) target; if (imageId < 0) { return imageView.getDrawable() == null; } Resources resources = target.getContext().getResources(); Drawable expectedDrawable = resources.getDrawable(imageId, null); if (expectedDrawable == null) { return false; } Drawable imageDrawable = imageView.getDrawable(); ColorFilter imageColorFilter = imageDrawable.getColorFilter(); expectedDrawable.setColorFilter(imageColorFilter); expectedDrawable.setTintList(target.getResources() .getColorStateList(tintId, null)); boolean areSame = areDrawablesIdentical(imageDrawable, expectedDrawable); return areSame; } public 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 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; } @Override public void describeTo(Description description) { } }; }
fuente
Compare 2 dibujables:
drawable1.constantState == drawable2.constantState || drawable1.toBitmap().sameAs(drawable2.toBitmap())
Si no puede encontrar
Drawable.toBitmap(...)
aquí es Drawable.ktfuente
si desea comparar directamente dos dibujables, use el siguiente código
Dibujable fDraw = getResources (). GetDrawable (R.drawable.twt_hover);
Dibujable sDraw = getResources (). GetDrawable (R.drawable.twt_hover);
if (fDraw.getConstantState().equals(sDraw.getConstantState())) { //write your code. } else { //write your code. }
fuente
Cuando usa el
equals()
método, se usa para comparar el contenido. debe intentar==
comparar dos objetos.public void MyClick(View view) { Drawable fDraw = view.getBackground(); Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover); if( fDraw == sDraw ) { // Coming } }
fuente