Bagaimana membandingkan dua drawable, saya melakukan seperti ini tetapi tidak berhasil
public void MyClick(View view)
{
Drawable fDraw = view.getBackground();
Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover);
if(fDraw.equals(sDraw))
{
//Not coming
}
}
Jawaban:
Perbarui https://stackoverflow.com/a/36373569/1835650
getConstantState () tidak berfungsi dengan baik
Ada cara lain untuk membandingkan:mRememberPwd.getDrawable().getConstantState().equals (getResources().getDrawable(R.drawable.login_checked).getConstantState());
mRemeberPwd
adalahImageView
dalam contoh ini. Jika Anda menggunakanTextView
, gunakangetBackground().getConstantState
saja.sumber
Mengandalkan diri
getConstantState()
sendiri dapat menghasilkan negatif palsu .Pendekatan yang saya ambil adalah mencoba membandingkan ConstantState pada contoh pertama, tetapi kembali pada perbandingan Bitmap jika pemeriksaan itu gagal.
Ini harus bekerja di semua kasus (termasuk gambar yang bukan sumber daya) tetapi perhatikan bahwa itu haus memori.
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; }
sumber
getConstantState()
perbandingansetBounds
dandraw
pada salinan sebagai ganti stackoverflow.com/a/25462223/1916449 asliPertanyaan saya adalah hanya membandingkan dua drawable, saya mencoba tetapi tidak bisa mendapatkan metode apa pun yang secara langsung membandingkan dua drawable, namun untuk solusi saya, saya mengubah drawable menjadi bitmap dan kemudian membandingkan dua bitmap dan itu berfungsi.
Bitmap bitmap = ((BitmapDrawable)fDraw).getBitmap(); Bitmap bitmap2 = ((BitmapDrawable)sDraw).getBitmap(); if(bitmap == bitmap2) { //Code blcok }
sumber
untuk SDK 21+
ini berfungsi di SDK -21
mRememberPwd.getDrawable().getConstantState().equals (getResources().getDrawable(R.drawable.login_checked).getConstantState())
untuk SDK +21 android 5. setel id drawable ke imageview dengan tag
img.setTag(R.drawable.xxx);
dan bandingkan seperti ini
if ((Integer) img.getTag() == R.drawable.xxx) { ....your code }
solusi ini untuk yang ingin membandingkan
drawable
idimageview
dengan iddrawable.xxx
.sumber
Solusi untuk Android 5:
if(image.getDrawable().getConstantState().equals(image.getContext().getDrawable(R.drawable.something).getConstantState()))
sumber
getDrawable (int) Sekarang Tidak Digunakan Lagi. Gunakan getDrawable (konteks, R.drawable.yourimageid)
Untuk Membandingkan Dua Latar Belakang
Boolean Condition1=v.getBackground().getConstantState().equals( ContextCompat.getDrawable(getApplicationContext(),R.drawable.***).getConstantState());
sumber
context.getResources().getDrawable(R.drawable.***)
pada Android 6+ tetapi tidak pada Android 5. Dengan perubahan kecil ini, saya dapat membandingkan drawable latar belakang di semua versi Android dengan sempurnamungkin mencobanya dengan cara ini:
public void MyClick(View view) { Drawable fDraw = view.getBackground(); Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover); if(fDraw.hashCode() == sDraw.hashCode()) { //Not coming } }
atau persiapkan metode yang mengambil dua argumen drawable dan mengembalikan boolean. Dalam metode itu, Anda dapat mengonversi drawable menjadi byte dan membandingkan,
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; }
sumber
e.g R.drawable.abc
kedua parameter?Oke, saya rasa saya telah menemukan solusi pamungkas untuk ini. Karena AppCompat dan teman-teman, drawable yang disediakan terkadang digelembungkan dalam berbagai bentuk sehingga tidak cukup untuk dilakukan
getResources().getBitmap(R.drawable.my_awesome_drawable)
.Jadi, untuk mendapatkan instance drawable dari jenis dan bentuk yang sama seperti yang disediakan oleh tampilan, seseorang dapat melakukan ini:
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); } }
Ini berguna saat melakukan tes. Namun, saya tidak akan merekomendasikan melakukan ini dalam produksi. Jika Anda perlu, cache tambahan akan diinginkan untuk menghindari melakukan terlalu banyak refleksi.
Untuk pengujian Expresso, Anda dapat menggunakan ini dengan cukup baik:
onView(withDrawable(R.drawable.awesome_drawable)) .check(matches(isDisplayed()));
atau
onView(withId(R.id.view_id)) .check(matches(withDrawable(R.drawable.awesome_drawable)));
Sebelum Anda harus mendeklarasikan kelas helper ini:
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); } } } }
sumber
sumber
Saya sudah menjawab tentang topik serupa di sini: Dapatkan ID drawable di ImageView . Pendekatan ini didasarkan pada pemberian tag pada tampilan dengan id sumber daya yang ditentukan di kustom
LayoutInflater
. Seluruh proses diotomatiskan oleh pustaka TagView sederhana .Hasilnya, Anda bisa membandingkan dua drawable hanya dengan idnya:
sumber
Memperluas jawaban dari @vaughandroid, Matcher berikut berfungsi untuk Drawable Vektor yang diwarnai. Anda harus memberikan warna yang digunakan untuk Drawable tersebut.
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) { } }; }
sumber
Bandingkan 2 drawable:
drawable1.constantState == drawable2.constantState || drawable1.toBitmap().sameAs(drawable2.toBitmap())
Jika Anda tidak dapat menemukannya di
Drawable.toBitmap(...)
sini adalah Drawable.ktsumber
Jika Anda ingin membandingkan dua drawable secara langsung, gunakan kode berikut
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. }
sumber
Ketika Anda menggunakan
equals()
metode ini digunakan untuk membandingkan konten. Anda harus mencoba==
membandingkan dua objek.public void MyClick(View view) { Drawable fDraw = view.getBackground(); Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover); if( fDraw == sDraw ) { // Coming } }
sumber