Получить ID отрисовки в ImageView - PullRequest
47 голосов
/ 24 декабря 2010

У меня есть один ImageView и я нарисую его. Теперь мне нужно получить идентификатор события рисования при нажатии ImageView динамически. Как я могу получить это?

imgtopcolor = (ImageView) findViewById(R.id.topcolor); 
imgtopcolor.setImageResource(R.drawable.dr);  // How do I get this back?

Теперь при событии касания imgtopcolor мне нужен идентификатор рисования, потому что я каждый раз настраиваю разные рисунки и хочу сравнить рисунок с другими

Ответы [ 7 ]

50 голосов
/ 25 декабря 2010

Я думаю, если я правильно понимаю, это то, что вы делаете.

ImageView view = (ImageView) findViewById(R.id.someImage);
view.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        ImageView imageView = (ImageView) view;
        assert(R.id.someImage == imageView.getId());

        switch(getDrawableId(imageView)) {
            case R.drawable.foo:
                imageView.setDrawableResource(R.drawable.bar);
                break;
            case R.drawable.bar:
            default:
                imageView.setDrawableResource(R.drawable.foo);
            break;
        }
    });

Верно?Так что эта функция getDrawableId() не существует.Вы не можете получить идентификатор, из которого был создан экземпляр Drawable, потому что идентификатор - это просто ссылка на расположение данных на устройстве о том, как создать Drawable.Как только нарисованный объект создан, у него нет способа вернуть ресурсный идентификатор, который использовался для его создания.Но вы можете заставить его работать примерно так, используя теги

ImageView view = (ImageView) findViewById(R.id.someImage);
view.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        ImageView imageView = (ImageView) view;
        assert(R.id.someImage == imageView.getId());

        // See here
        Integer integer = (Integer) imageView.getTag();
        integer = integer == null ? 0 : integer;

        switch(integer) {
        case R.drawable.foo:
            imageView.setDrawableResource(R.drawable.bar);
            imageView.setTag(R.drawable.bar);
            break;
        case R.drawable.bar:
        default:
            imageView.setDrawableResource(R.drawable.foo);
            imageView.setTag(R.drawable.foo);
            break;
        }
    });
29 голосов
/ 23 января 2013

Я уже ответил на что-то подобное в другом вопросе, но немного поменяю на этот.

К сожалению, нет getImageResource() или getDrawableId(). Но я создал простой обходной путь с помощью тегов ImageView.

В onCreate ():

imageView0 = (ImageView) findViewById(R.id.imageView0);
imageView1 = (ImageView) findViewById(R.id.imageView1);
imageView2 = (ImageView) findViewById(R.id.imageView2);

imageView0.setTag(R.drawable.apple);
imageView1.setTag(R.drawable.banana);
imageView2.setTag(R.drawable.cereal);

Затем, если хотите, вы можете создать простую функцию для получения идентификатора для рисования:

private int getDrawableId(ImageView iv) {
    return (Integer) iv.getTag();
}

Слишком просто.

5 голосов
/ 28 сентября 2016

На сегодняшний день эта функция не поддерживается.Тем не менее, я нашел небольшой взлом на этом.

 imageView.setImageResource(R.drawable.ic_star_black_48dp);
 imageView.setTag(R.drawable.ic_star_black_48dp);

Так что если вы хотите получить идентификатор представления, просто получите его тег.

if (imageView.getTag() != null) {
   int resourceID = (int) imageView.getTag();

   //
   // drawable id.
   //   
}
1 голос
/ 21 марта 2018

Копание StackOverflow для получения ответов на аналогичную проблему. Я нашел людей, обычно предлагающих 2 подхода:

  • Загрузите в память отрисовку и сравните ConstantState или сам растр с другим.1006 *
  • Установите тег с отображаемым идентификатором в представление и сравните теги, когда вам это нужно.

Лично мне нравится второй подход по соображениям производительности, но пометка группы представлений соответствующими тегамибольно и отнимает много времени.Это может быть очень сложно в большом проекте.В моем случае мне нужно написать множество тестов для эспрессо, которые требуют сравнения TextView ресурсов рисования, ImageView ресурсов, View фона и переднего плана.Много работы.

Так что в итоге я пришел к решению, чтобы делегировать «грязную» работу пользовательскому инфлятору.В каждом завышенном представлении я выполняю поиск определенных атрибутов и устанавливаю тег для представления с идентификатором ресурса, если таковой найден.Этот подход в значительной степени используется теми же парнями из Каллиграфия .Я написал для этого простую библиотеку: TagView

Если вы используете ее, вы можете извлечь любой из предопределенных тегов, содержащих идентификатор нарисованного ресурса, который был установлен в файле макета xml:

TagViewUtils.getTag(view, ViewTag.IMAGEVIEW_SRC.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_LEFT.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_TOP.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_RIGHT.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_BOTTOM.id)
TagViewUtils.getTag(view, ViewTag.VIEW_BACKGROUND.id)
TagViewUtils.getTag(view, ViewTag.VIEW_FOREGROUND.id)

Библиотека фактически поддерживает любой атрибут.Вы можете добавить их вручную, просто загляните в раздел Пользовательские атрибуты на Github.Если вы устанавливаете рисование во время выполнения, вы можете использовать удобные библиотечные методы:

setImageViewResource(ImageView view, int id)

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

fun ImageView.setImageResourceWithTag(@DrawableRes int id) {
    TagViewUtils.setImageViewResource(this, id)
}

Дополнительную информацию можно найти в Пометка во время выполнения

1 голос
/ 25 декабря 2010

Простое решение может состоять в том, чтобы просто сохранить рисуемый идентификатор во временной переменной.Я не уверен, насколько это будет практично для вашей ситуации, но это определенно быстрое решение.

0 голосов
/ 21 марта 2019

Я недавно столкнулся с той же проблемой.Я решил это путем реализации своего собственного класса ImageView .

Вот моя реализация Kotlin :

class MyImageView(context: Context): ImageView(context) {
    private var currentDrawableId: Int? = null

    override fun setImageResource(resId: Int) {
        super.setImageResource(resId)
        currentDrawableId = resId
    }

    fun getDrawableId() {
        return currentDrawableId
    }

    fun compareCurrentDrawable(toDrawableId: Int?): Boolean {
        if (toDrawableId == null || currentDrawableId != toDrawableId) {
            return false
        }

        return true
    }

}
0 голосов
/ 19 мая 2014

Еще проще: просто сохраните идентификатор R.drawable в идентификаторе представления: используйте v.setId(). Затем верните его с помощью v.getId().

...