Comparing two drawables in android
Update
https://stackoverflow.com/a/36373569/1835650
getConstantState() works not well
There is another way to compare:
mRememberPwd.getDrawable().getConstantState().equals
(getResources().getDrawable(R.drawable.login_checked).getConstantState());
mRemeberPwd
is an ImageView
in this example. If you're using a TextView
, use getBackground().getConstantState
instead.
How to Comparing two drawables in android
The most straightforward solution to this would be to set a tag to the ImageView whenever you are setting the drawable and then later checking the tag set to the ImageView.
Something like this :
When you are setting drawable1 to the imageView1, do imageView1.setTag("drawable1")
When you want to check the drawable in imageView1, you can simply go imageView1.getTag()
//populerer buttons med images
for(int i = 0; i < buttons.size(); i++) {
int random = r.nextInt(buttons.size());
while(printedImagesIDs.contains(random))
random = r.nextInt(buttons.size());
buttons.get(i).setImageResource(imageIDs[random]);
buttons.get(i).setTag("" +imageIDs[random]); //set the tag while setting the drawable
printedImagesIDs.add(random);
}
if(((String)klikk1.getTag()).equals((String)klikk2.getTag())){//get and match the tags
turnstate = true;
}
Comparing resources within two drawables
getConstantState doesn't work well
If you do this: if(drawable1 == drawable2){
you are comparing the reference of the objects and it not correct...
use instead equals with the getConstantState()
method...
Update Try to compare with bytes or pixel is the only way that generally works.
// Usage:
drawable1.bytesEqualTo(drawable2)
drawable1.pixelsEqualTo(drawable2)
bitmap1.bytesEqualTo(bitmap1)
bitmap1.pixelsEqualTo(bitmap2)
https://gist.github.com/XinyueZ/3cca89416a1e443f914ed37f80ed59f2
Comparing two VectorDrawables fails in Kaspresso - Android
The issue was because actually the image is scaled. So the scaled image is different from the original one.
To avoid this issue I've used this "altered" KImageView:
package your_package
import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.PorterDuff
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.StateListDrawable
import android.os.Build
import android.view.View
import android.widget.ImageView
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.core.graphics.drawable.DrawableCompat
import androidx.test.espresso.DataInteraction
import androidx.test.espresso.assertion.ViewAssertions
import com.agoda.kakao.common.assertions.BaseAssertions
import com.agoda.kakao.common.builders.ViewBuilder
import com.agoda.kakao.common.utilities.getResourceColor
import com.agoda.kakao.common.utilities.getResourceDrawable
import com.agoda.kakao.common.views.KBaseView
import com.agoda.kakao.image.KImageView
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.TypeSafeMatcher
class KImageView2 : KBaseView<KImageView>, ImageViewAssertions2 {
constructor(function: ViewBuilder.() -> Unit) : super(function)
constructor(parent: Matcher<View>, function: ViewBuilder.() -> Unit) : super(parent, function)
constructor(parent: DataInteraction, function: ViewBuilder.() -> Unit) : super(parent, function)
}
interface ImageViewAssertions2 : BaseAssertions {
/**
* Checks if the view displays given drawable
*
* @param resId Drawable resource to be matched
* @param toBitmap Lambda with custom Drawable -> Bitmap converter (default is null)
*/
fun hasDrawable(@DrawableRes resId: Int, toBitmap: ((drawable: Drawable) -> Bitmap)? = null) {
view.check(ViewAssertions.matches(DrawableMatcher2(resId = resId, toBitmap = toBitmap)))
}
}
class DrawableMatcher2(
@DrawableRes private val resId: Int = -1,
@ColorRes private val tintColorId: Int? = null,
private val toBitmap: ((drawable: Drawable) -> Bitmap)? = null
) : TypeSafeMatcher<View>(View::class.java) {
override fun describeTo(desc: Description) {
desc.appendText("with drawable id $resId or provided instance")
}
override fun matchesSafely(view: View?): Boolean {
if (view !is ImageView) {
return false
}
if (resId < 0) {
return view.drawable == null
}
val bitmap = extractFromImageView(view)
view.setImageResource(resId)
val otherBitmap = extractFromImageView(view)
return bitmap?.sameAs(otherBitmap) ?: false
}
private fun extractFromImageView(view: View?): Bitmap? {
return view?.let { imageView ->
var expectedDrawable: Drawable? = getResourceDrawable(resId)?.mutate()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && expectedDrawable != null) {
expectedDrawable = DrawableCompat.wrap(expectedDrawable).mutate()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
tintColorId?.let { tintColorId ->
val tintColor = getResourceColor(tintColorId)
expectedDrawable?.apply {
setTintList(ColorStateList.valueOf(tintColor))
setTintMode(PorterDuff.Mode.SRC_IN)
}
}
}
if (expectedDrawable == null) {
return null
}
val convertDrawable = (imageView as ImageView).drawable.mutate()
toBitmap?.invoke(convertDrawable) ?: convertDrawable.toBitmap()
}
}
}
internal fun Drawable.toBitmap(): Bitmap {
if (this is BitmapDrawable && this.bitmap != null) {
return this.bitmap
}
if (this is StateListDrawable && this.getCurrent() is BitmapDrawable) {
val bitmapDrawable = this.getCurrent() as BitmapDrawable
if (bitmapDrawable.bitmap != null) {
return bitmapDrawable.bitmap
}
}
val bitmap = if (this.intrinsicWidth <= 0 || this.intrinsicHeight <= 0) {
Bitmap.createBitmap(
1,
1,
Bitmap.Config.ARGB_8888
) // Single color bitmap will be created of 1x1 pixel
} else {
Bitmap.createBitmap(this.intrinsicWidth, this.intrinsicHeight, Bitmap.Config.ARGB_8888)
}
val canvas = Canvas(bitmap)
this.setBounds(0, 0, canvas.width, canvas.height)
this.draw(canvas)
return bitmap
}
Not the cleanest solution possible, but it works. If anyone can provide a better solution would be great :-)
Related Topics
Android Hide/Unhide App Icon Programmatically
Show Timepicker with Minutes Intervals in Android
Android - File Provider - Permission Denial
Passing String Array Between Android Activities
How to Use Assert on Android Devices
Failed to Find Style 'Coordinatorlayoutstyle' in Current Theme
How to Write Vertically in a Textview in Android
How to Implement Filterable in Realmrecyclerviewadapter
How to Make Constraintlayout Work with Percentage Values
Mediacodec and Camera: Colorspaces Don't Match
How to Make an Application Ignore Screen Orientation Change
Gles10.Glgetintegerv Returns 0 in Lollipop Only
How to Create a Help Overlay Like You See in a Few Android Apps and Ics
How to Add a Library (Android-Support-V7-Appcompat) in Intellij Idea