API getResources (). Застарілий API 22 getDravable ()


700

З новим Android 22 API getResources().getDrawable()тепер застаріло. Зараз найкращим підходом є лише використання getDrawable().

Що змінилося?


Не могли б ви вказати своє запитання? Правильно, що метод getDrawable (int id)класу Resourcesзастарілий. Тепер ви повинні використовувати метод getDrawable (int id, Resources.Theme theme)з новим параметром теми.
кодова мавпа

1
ContextCompat.getDrawable (контекст, R.color.color_name)
Ashokchakravarthi Nagarajan

Ви можете ознайомитись з моєю публікацією в цьому блозі, щоб отримати більш ретельне пояснення щодо того, чому обидва Resources#getDrawable(int)і Resources#getColor(int)як застаріли.
Алекс Локвуд

1
Google має ввести швидкі виправлення для кожної застарілої функції. Я написав про це повідомлення тут: code.google.com/p/android/isissue/detail?id=219495
андроїд розробник

Відповіді:


1028

У вас є кілька варіантів вирішити цю депресію правильним (і майбутнім доказом ) способом, залежно від того, який тип малювання ви завантажуєте:


А) малюнки з атрибутами теми

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

Ви отримаєте стилізований графічний малюнок у відповідності до теми своєї діяльності. Це, мабуть, те, що вам потрібно.


В) малюнки без атрибутів теми

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

Ви отримаєте своє неспокійне малювання старим способом. Будь ласка , зверніть увагу: ResourcesCompat.getDrawable()це НЕ рекомендується!


EXTRA) малюнки з атрибутами теми з іншої теми

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

Мій додаток виходить з ладу через пропозицію B. Це не любить виклик Dravable originalIcon = ResourcesCompat.getDravable (ctxt.getResources (), iconResId, null);
FractalBob

Я заявляю про це таким чином: загальнодоступний статичний недійсний setImageButtonEnabled (контекст ctxt, включений бул, елемент ImageButton, int iconResId) {item.setEnabled (увімкнено); Dravable originalIcon = ResourcesCompat.getDravable (ctxt.getResources (), iconResId, null); Значок для малювання = увімкнено? originalIcon: convertDravableToGrayScale (originalIcon); item.setImageDravable (значок); } і називати це так: Utility.setImageButtonEnabled (getContext (), false, назад, R.dravable.arrow_left);
FractalBob

Точніше, збій, здається, відбувається тому, що мій значок - це векторний малюнок.
FractalBob

1
версія xamarin: ResourcesCompat.GetDrawable (Resources, Resource.Dravable.name, null);
Брайан

Додаю ще одне слово до вас , ContextCompat.getColor (контекст, колір) також може допомогти вам ...
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
Згідно з документацією, для використання потрібно мінімальний рівень 21 рівня getDrawable(int, Resources.Theme).
Принц

@Prince Метод був доданий в API 21, але його не було застаріло до API 22. :)
Алекс Локвуд,

Android doc також рекомендує використовувати метод Context :: getDravable (int), але оскільки він був представлений лише в API 21, здається, що ContextCompat є найкращим вибором.
goRGon

Ця відповідь не працює з .svg файлами у версіях, старших за API 21. У бібліотеці є помилка.
Хорхе Родрігес

141

Замініть цей рядок: getResources().getDrawable(R.drawable.your_drawable)

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

EDIT

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застаріле. Це має добре працювати.
Яків R

що писати у "вашому малюванні", якщо я хочу вводити зображення до переліку списку, натиснувши елементи списку, що зберігаються у малюванні
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);

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


Використання контексту програми для завантаження векторних драйвових збоїв на попередньому льодянику. Будь-яке виправлення для цього?
мутурай

1
@muthuraj Я не пам’ятаю свого тестування на код з регістром льодяника, але ви можете спробувати getActivity () або getResources () замість цього, чи добре це відповідає вашому коду?
Дассер Басюні

Я використовую шаблон MVVM, і мені потрібно надути чернетки в ViewModels, які не мають контексту діяльності. Він має лише контекст застосування. Ось в чому моє питання.
мутурай

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)

Сподіваюся, це допоможе вам. Дякую.


Варто зазначити, що getDravable (DravableRes int id, тема теми) може викинути виняток, якщо ресурс не знайдений, а getDrawable (контекст контексту, int id) є нульовим, тому його потрібно повернути за допомогою Dravable? в Котліні.
Пітос


0

Тепер вам потрібно реалізувати так

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

Після одного рядка коду достатньо, про все подбає ContextCompat.getDravable

ContextCompat.getDrawable(this, R.drawable.your_drawable_file)

0

Для тих, хто все-таки отримав цю проблему для вирішення навіть після застосування пропозиції цього потоку (я раніше був подібний), додайте цей рядок у свій клас застосунку, метод onCreate ()

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

Як запропоновано тут і тут, іноді це потрібно для доступу до векторів із ресурсів, особливо коли ви маєте справу з пунктами меню тощо


0

У Котліні ви можете використовувати розширення

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.