Android getResources (). GetDrawable () устарел API 22

700

С новым Android API 22 getResources().getDrawable()теперь устарела. Теперь лучшим подходом является использование только getDrawable().

Что изменилось?

Blodhgard
источник
Не могли бы вы указать свой вопрос? Это верно, что метод getDrawable (int id)класса Resourcesустарел. Теперь вы должны использовать метод getDrawable (int id, Resources.Theme theme)с новым параметром темы.
код обезьяны
1
ContextCompat.getDrawable (context, R.color.color_name)
Ашокчакраварти Нагараджан
Вы можете проверить мой пост в блоге на эту тему для более подробного объяснения того, почему и то, Resources#getDrawable(int)и другое Resources#getColor(int)устарели.
Алекс Локвуд
1
Google должен поставить быстрые исправления для каждой устаревшей функции. Я сделал сообщение об этом здесь: code.google.com/p/android/issues/detail?id=219495
разработчик Android

Ответы:

1028

У вас есть несколько вариантов, чтобы справиться с этим устареванием правильным (и перспективным ) способом, в зависимости от того, какой вид рисования вы загружаете:


А) Drawables с атрибутами темы

ContextCompat.getDrawable(getActivity(), R.drawable.name);

Вы получите стиль Drawable в соответствии с инструкциями вашей темы. Это, вероятно, то, что вам нужно.


Б) рисования без атрибутов темы

ResourcesCompat.getDrawable(getResources(), R.drawable.name, null);

Вы получите свой стиль без рисунка по-старому. Обратите внимание: неResourcesCompat.getDrawable() считается устаревшим!


ДОПОЛНИТЕЛЬНО) Drawables с атрибутами темы из другой темы

ResourcesCompat.getDrawable(getResources(), R.drawable.name, anotherTheme);
Аракс
источник
Мое приложение аварийно завершает работу по предложению B. Ему не нравится вызов Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null);
FractalBob
Я объявляю это следующим образом: public static void setImageButtonEnabled (контекст ctxt, логическое значение включено, элемент ImageButton, int iconResId) {item.setEnabled (включено); Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null); Drawable icon = включен? originalIcon: convertDrawableToGrayScale (originalIcon); item.setImageDrawable (иконка); } и вызвать его так: Utility.setImageButtonEnabled (getContext (), false, back, R.drawable.arrow_left);
FractalBob
Точнее, сбой, кажется, происходит, потому что мой значок - это векторное изображение.
FractalBob
1
xamarin версия: ResourcesCompat.GetDrawable (Resources, Resource.Drawable.name, null);
Брайан
Я добавлю еще одно слово к вам , ContextCompat.getColor (context, color) также может помочь вам ...
BertKing
746

Изменить: см. Мой блог на эту тему для более полного объяснения


Вместо этого вы должны использовать следующий код из библиотеки поддержки:

ContextCompat.getDrawable(context, R.drawable.***)

Использование этого метода эквивалентно вызову:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    return resources.getDrawable(id, context.getTheme());
} else {
    return resources.getDrawable(id);
}

Начиная с API 21, вы должны использовать getDrawable(int, Theme) метод вместо getDrawable(int), так как он позволяет вам выбирать рисуемый объект, связанный с конкретным идентификатором ресурса для данной плотности экрана / темы. Вызов устаревшего getDrawable(int)метода эквивалентен вызову getDrawable(int, null).

Алекс Локвуд
источник
8
Я думаю, что ОП также относится к getDrawable (int id)методу Contextкласса. Это то же самое, что getResources().getDrawable(id, getTheme());и новый API.
код обезьяны
9
Согласно документации, минимальный уровень API 21 требуется для использования getDrawable(int, Resources.Theme).
Принц
@Prince Метод был добавлен в API 21, но до API 22 он не устарел. :)
Алекс Локвуд
Android doc также рекомендует использовать метод Context :: getDrawable (int), но так как он был представлен только в API 21, кажется, что ContextCompat - лучший выбор.
goRGon
Этот ответ не работает с файлами .svg в версиях старше API 21. В библиотеке есть ошибка.
Хорхе Родригес
141

Заменить эту строку: getResources().getDrawable(R.drawable.your_drawable)

с ResourcesCompat.getDrawable(getResources(), R.drawable.your_drawable, null)

РЕДАКТИРОВАТЬ

ResourcesCompatтакже не рекомендуется сейчас. Но вы можете использовать это:

ContextCompat.getDrawable(this, R.drawable.your_drawable)(Вот thisконтекст)

для более подробной информации перейдите по этой ссылке: ContextCompat

vincent091
источник
2
Это тоже теперь запрещено: plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBM
Xyaren
перейдите по этой ссылке, пожалуйста: developer.android.com/reference/android/support/v4/content/… , int)
vincent091
2
В ссылке не сказано, что ResourcesCompatэто устарело. Это должно работать нормально.
Джейкоб Р
что писать в «своем рисованном виде», если я хочу вводить изображения в виде списка, щелкая элементы списка, сохраненные в рисованном виде
0x0001
29

getResources().getDrawable() устарел на уровне API 22. Теперь мы должны добавить тему:

getDrawable (int id, тема Resources.Theme) (добавлено на уровне API 21)

Это пример:

myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage, getApplicationContext().getTheme()));

Это пример того, как проверить для более поздних версий:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
     myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage, getApplicationContext().getTheme()));
   } else { 
     myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage));
}
Jorgesys
источник
Build.VERSION_CODES.LOLLIPOP is API 21Так не должно ли это быть if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)или if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)? Ничего. Снизу «Метод был добавлен в API 21, но не обновлялся до API 22. :)»
Марк Крамер
2

Ты можешь использовать

ContextCompat.getDrawable(getApplicationContext(),R.drawable.example);

это работа для меня

Дасер Басьюни
источник
Использование контекста приложения для загрузки векторных отрисовываемых сбоев в pre lollipop. Любое исправление для этого?
Muthuraj
1
@muthuraj Я не помню, чтобы я тестировал код для случая с леденцом на палочке, но вместо этого вы можете попробовать getActivity () или getResources (), хорошо ли это подходит для вашего кода?
Дасер Басьюни,
Я использую шаблон MVVM, и мне нужно накачать надстройки внутри ViewModels, которые не имеют контекста активности. У него есть только контекст приложения. Вот в чем моя проблема.
Muthuraj
1

Просто пример того, как я исправил проблему в массиве для загрузки listView, надеюсь, это поможет.

 mItems = new ArrayList<ListViewItem>();
//    Resources resources = getResources();

//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.az_lgo), getString(R.string.st_az), getString(R.string.all_nums)));
//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.ca_lgo), getString(R.string.st_ca), getString(R.string.all_nums)));
//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.co_lgo), getString(R.string.st_co), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.az_lgo, null), getString(R.string.st_az), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.ca_lgo, null), getString(R.string.st_ca), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.co_lgo, null), getString(R.string.st_co), getString(R.string.all_nums)));
сойка
источник
1

Попробуй это:

public static List<ProductActivity> getCatalog(Resources res){
    if(catalog == null) {
        catalog.add(new Product("Dead or Alive", res
                .getDrawable(R.drawable.product_salmon),
                "Dead or Alive by Tom Clancy with Grant Blackwood", 29.99));
        catalog.add(new Product("Switch", res
                .getDrawable(R.drawable.switchbook),
                "Switch by Chip Heath and Dan Heath", 24.99));
        catalog.add(new Product("Watchmen", res
                .getDrawable(R.drawable.watchmen),
                "Watchmen by Alan Moore and Dave Gibbons", 14.99));
    }
}
Сякирин Мохд Нор
источник
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, почему и / или как этот код отвечает на вопрос, повышает его долгосрочную ценность.
Дональд Дак
1

Если вы нацеливаетесь на SDK> 21 (леденец или 5.0), используйте

context.getDrawable(R.drawable.your_drawable_name)

См документы

Адель Ахмад
источник
1

getDrawable (int drawable) устарела на уровне API 22. Для справки см. эту ссылку .

Теперь, чтобы решить эту проблему, мы должны передать новый конструктор вместе с id как:

getDrawable(int id, Resources.Theme theme)

Для решений Сделайте так: -

В Java: -

ContextCompat.getDrawable(getActivity(), R.drawable.name);   

или

 imgProfile.setImageDrawable(getResources().getDrawable(R.drawable.img_prof, getApplicationContext().getTheme()));

В Котлине: -

rel_week.background=ContextCompat.getDrawable(this.requireContext(), R.color.colorWhite)

или

 rel_day.background=resources.getDrawable(R.drawable.ic_home, context?.theme)

Надеюсь, это поможет вам. Спасибо.

Рахул Кушваха
источник
Стоит отметить, что getDrawable (DrawableRes int id, тема Theme) может вызвать исключение, если ресурс не найден, в то время как getDrawable (Context context, int id) имеет значение null, поэтому его нужно возвращать с Drawable? в Котлине.
Питос
0

en api level 14

marker.setIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.miubicacion, null));
Хайме Лопес Ромеро
источник
Вы должны предоставить немного больше контекста вокруг вашего ответа.
Николя Гренье
0

Теперь вам нужно реализовать так

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
        //
    } else {
        //
    }

Достаточно одной строки кода, все позаботится о ContextCompat.getDrawable

ContextCompat.getDrawable(this, R.drawable.your_drawable_file)
Фарид Хак
источник
0

Для тех, кто все еще может решить эту проблему даже после применения предложения этого потока (я был таким), добавьте эту строку в свой класс Application, метод onCreate ()

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

Как предлагается здесь и здесь, иногда это требуется для доступа к векторам из ресурсов, особенно когда вы имеете дело с пунктами меню и т. Д.

Стаматис Стилиатс
источник
0

В Kotlin вы можете использовать расширение

fun Context.getMyDrawable(id : Int) : Drawable?{

    return  ContextCompat.getDrawable(this, id)
}

затем использовать как

context.getMyDrawable(R.drawable.my_icon)
Дипак Канян
источник
-2

Build.VERSION_CODES.LOLLIPOP теперь должен быть изменен на BuildVersionCodes.Lollipop, то есть:

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder, Context.Theme);
} else {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder);
}
Райан Герман
источник
Разве BuildVersionCodesкласс не специфичен для Xamarin?
Тед Хопп