Сравнение .getBackground () с getDrawable [duplicate]

Простой вариант использования с aggregate - это функция length, которая даст вам длину вектора в подмножестве. Иногда немного более надежным является использование function(x) sum( !is.na(x) ).

78
задан Lalit Poptani 3 February 2012 в 09:40
поделиться

12 ответов

Обновить https://stackoverflow.com/a/36373569/1835650

getConstantState () работает не очень хорошо

Есть еще один способ сравнения :

mRememberPwd.getDrawable().getConstantState().equals
            (getResources().getDrawable(R.drawable.login_checked).getConstantState());
mRemeberPwd является ImageView в этом примере. Если вы используете TextView, используйте getBackground().getConstantState.

146
ответ дан TeeTracker 21 August 2018 в 13:53
поделиться
  • 1
    Это решение работает, и оно лучше, поскольку оно позволяет избежать преобразования Drawable в Bitmap и сравнить. – Braj 9 August 2013 в 12:34
  • 2
    Не всегда: WallpaperManager.getInstance (this) .getFastDrawable (). GetConstantState () имеет значение null. – bluewhile 29 November 2013 в 02:28
  • 3
    Извините, что в последнее время я принимаю это как ответ и меняю свой ответ, так как это кажется лучшим вариантом (и больше upvotes также :)). Поэтому проверяем это как ответ. – Roshan Jha 20 February 2014 в 13:47
  • 4
    Спасибо, это лучший ответ – satyres 5 August 2014 в 23:31
  • 5
    Этот код отлично работает на устройствах ниже 5.0, но im получает ошибки, используя его на устройстве 5.0, может ли кто-нибудь подтвердить, что этот метод работает или нет на Android 5.0 или выше – Phil3992 17 December 2014 в 15:18

, если вы хотите напрямую сравнить два выталкиваемых, используйте следующий код

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.
}
-1
ответ дан Addon.mahesh 21 August 2018 в 13:53
поделиться

Я уже ответил на аналогичную тему здесь: Получите идентификатор drawable в ImageView . Подход основан на пометке представления с указанным идентификатором ресурса в пользовательском LayoutInflater. Весь процесс автоматизируется с помощью простой библиотеки TagView .

В результате вы можете сравнить две строки с помощью своих идентификаторов:

TagViewUtils.getTag(view, ViewTag.VIEW_BACKGROUND.id) == R.drawable.twt_hover
0
ответ дан Bogdan Kornev 21 August 2018 в 13:53
поделиться

Когда вы используете метод equals(), он используется для сравнения содержимого. вы должны попробовать == для сравнения двух объектов.

public void MyClick(View view)
{
 Drawable fDraw = view.getBackground();
 Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover);

  if( fDraw == sDraw )
  {
   // Coming
  }
}
-2
ответ дан Lucifer 21 August 2018 в 13:53
поделиться

Мой вопрос состоял в том, что мы просто сравнивали две чертежи, я пытался, но не смог получить какой-либо метод, который напрямую сравнивал бы два чертежа, однако для моего решения я изменил drawable на bitmap, а затем сравнил два растровых изображения и это работает.

Bitmap bitmap = ((BitmapDrawable)fDraw).getBitmap();
Bitmap bitmap2 = ((BitmapDrawable)sDraw).getBitmap();

if(bitmap == bitmap2)
    {
        //Code blcok
    }
8
ответ дан MKJParekh 21 August 2018 в 13:53
поделиться
  • 1
    это то, что я предлагаю вам, сравнить drawable в зависимости от типа drawable. – jeet 3 February 2012 в 11:04
  • 2
    Спасибо .. Работала для меня :) – Midhun 2 August 2012 в 06:32
  • 3
    Вы также можете сравнить битмапы следующим образом: stackoverflow.com/a/7696320/317889 – HGPB 12 April 2013 в 16:05
  • 4
    Это очень тяжело, поэтому подумайте об утилизации растровых изображений, или вы попадете в OutOfMemoryError! – bluewhile 29 November 2013 в 02:27
  • 5
    Почему вы можете сравнивать битмапы с равенством указателя (==)? Я ожидаю, что Bitmap.equals () понадобится. – Ellen Spertus 1 March 2014 в 00:55

Хорошо, я думаю, что нашел окончательное решение для этого. Из-за AppCompat и друзей предоставляемый ресурс иногда накачивается в разных формах, поэтому этого недостаточно 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);
    }
}

Это полезно при выполнении тестов. Однако я бы не рекомендовал делать это на производстве. Если вам нужно, потребуется дополнительное кэширование, чтобы избежать слишком большого отражения.

Для экспресс-тестов вы можете использовать это довольно хорошо:

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);
        }
     }
  }

}
2
ответ дан pablisco 21 August 2018 в 13:53
поделиться

Используйте getTag () и setTag () для сравнения

1
ответ дан Pooja Akshantal 21 August 2018 в 13:53
поделиться

getDrawable (int) теперь устарел. Использовать getDrawable (контекст, R.drawable.yourimageid)

Сравнить два фона

Boolean Condition1=v.getBackground().getConstantState().equals(
ContextCompat.getDrawable(getApplicationContext(),R.drawable.***).getConstantState());
0
ответ дан RAJESH KUMAR ARUMUGAM 21 August 2018 в 13:53
поделиться

Решение для Android 5:

 if(image.getDrawable().getConstantState().equals(image.getContext().getDrawable(R.drawable.something).getConstantState()))
4
ответ дан Tiago Santos 21 August 2018 в 13:53
поделиться

для SDK 21+

это работает в SDK -21

mRememberPwd.getDrawable().getConstantState().equals
        (getResources().getDrawable(R.drawable.login_checked).getConstantState())

для SDK +21 android 5. установите обратный идентификатор в изображение с тегом

img.setTag(R.drawable.xxx);

и сравнить это

if ((Integer) img.getTag() == R.drawable.xxx)
{
....your code
}

, это решение для тех, кто хочет сравнить drawable id imageview с id из drawable.xxx.

4
ответ дан tohid 21 August 2018 в 13:53
поделиться
  • 1
    На самом деле это работает, но я шокирован, почему нет другой возможности T_T! – error1337 27 June 2017 в 12:54

Опираясь только на 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 - 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;
}
30
ответ дан vaughandroid 21 August 2018 в 13:53
поделиться
  • 1
    Это на 100% верно и требует большего количества оборотов! Люди, пожалуйста, проверьте свой код с помощью известных Drawables, прежде чем сразу полагаться на сравнение getConstantState() – avalancha 9 November 2015 в 12:00
  • 2
    Это правильный ответ, сработал очень хорошо, спасибо – N J 7 October 2016 в 20:05
  • 3
    Хорошие результаты! Но согласно документации BitmapDrawable.getBitmap (), getBitmap () может быть нулевым, поэтому вы можете также проверить это – PhilLab 16 June 2017 в 16:25
  • 4
    Этот ответ верен, и я проверил, что после отладки нескольких часов с кодированием только getConstantState (). – Raghav Satyadev 11 July 2017 в 09:37
  • 5
    Чтобы быть в безопасности, setBounds и draw вместо копии stackoverflow.com/a/25462223/1916449 – arekolek 26 March 2018 в 21:00

, возможно, попробуйте это следующим образом:

public void MyClick(View view)
{
 Drawable fDraw = view.getBackground();
 Drawable sDraw = getResources().getDrawable(R.drawable.twt_hover);

  if(fDraw.hashCode() == sDraw.hashCode())
  {
   //Not coming
  }
}

или подготовьте метод, который принимает два допустимых аргумента и возвращает 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;
}
3
ответ дан waqaslam 21 August 2018 в 13:53
поделиться
  • 1
    это не работает – Roshan Jha 3 February 2012 в 10:03
  • 2
    проверьте обновленный ответ. если все еще не работает, проверьте свои чертежи. Или попробуйте передать те же чертежи, чтобы проверить функциональность кода – waqaslam 3 February 2012 в 10:18
  • 3
    да, после того, как я не добился успеха, я думаю, что для преобразования чертежей в растровое изображение, а затем в байт, позвольте мне попробовать, спасибо за ваши усилия – Roshan Jha 3 February 2012 в 10:33
  • 4
    не работает, вы его протестировали? может быть, есть что-то не так, не можем ли мы напрямую сравнить две возможности? – Roshan Jha 3 February 2012 в 10:47
  • 5
    вы пробовали его передавать одинаковые для e.g R.drawable.abc для обоих параметров? – waqaslam 3 February 2012 в 10:49
Другие вопросы по тегам:

Похожие вопросы: