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


700

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

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


Не могли бы вы указать свой вопрос? Это верно, что метод 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


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

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

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

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

  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?
Тед Хопп
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.