Android getResources (). GetDrawable () przestarzałe API 22


699

Z nowym Android API API 22 getResources().getDrawable()jest już przestarzałe. Teraz najlepszym rozwiązaniem jest użycie tylko getDrawable().

Co się zmieniło?


Czy możesz podać swoje pytanie? To prawda, że ​​metoda getDrawable (int id)klasy Resourcesjest przestarzała. Powinieneś teraz użyć metody getDrawable (int id, Resources.Theme theme)z nowym parametrem kompozycji.
kod małpa

1
ContextCompat.getDrawable (kontekst, nazwa_koloru.koloru)
Ashokchakravarthi Nagarajan

Możesz sprawdzić moje blogu na ten temat na bardziej dokładnym wyjaśnieniem, dlaczego zarówno Resources#getDrawable(int)i Resources#getColor(int)były przestarzałe.
Alex Lockwood,

1
Google powinien wprowadzić szybkie poprawki dla każdej przestarzałej funkcji. Napisałem o tym post tutaj: code.google.com/p/android/issues/detail?id=219495
programista Androida

Odpowiedzi:


1027

Masz kilka opcji, aby poradzić sobie z tą amortyzacją we właściwy (i przyszły ) sposób, w zależności od tego, jaki ładunek rysujesz ładujesz:


A) Drawables z atrybutami motywu

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

Otrzymasz styl Drawable zgodnie z instrukcją motywu aktywności. To prawdopodobnie potrzebujesz.


B) Drawable bez atrybutów motywu

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

Będziesz mógł wyciągać swój niestylowany styl po staremu. Uwaga: nieResourcesCompat.getDrawable() jest przestarzałe!


EXTRA) drawables z atrybutami motywu z innego motywu

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

Moja aplikacja ulega awarii przy użyciu sugestii B. Nie lubi połączenia Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null);
FractalBob

Deklaruję to w ten sposób: public static void setImageButtonEnabled (Context ctxt, boolean włączony, element ImageButton, int iconResId) {item.setEnabled (włączony); Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null); Ikona do rysowania = włączona? originalIcon: convertDrawableToGrayScale (originalIcon); item.setImageDrawable (ikona); } i nazwij to tak: Utility.setImageButtonEnabled (getContext (), false, back, R.drawable.arrow_left);
FractalBob

Mówiąc dokładniej, wydaje się, że katastrofa ma miejsce, ponieważ moja ikona jest rysowana wektorem.
FractalBob

1
wersja xamarin: ResourcesCompat.GetDrawable (Resources, Resource.Drawable.name, null);
Brian

Dodaję jeszcze jedno słowo, ContextCompat.getColor (kontekst, kolor) również może ci pomóc ...
BertKing

746

Edycja: zobacz mój post na blogu na ten temat, aby uzyskać pełniejsze wyjaśnienie


Zamiast tego należy użyć następującego kodu z biblioteki wsparcia:

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

Użycie tej metody jest równoważne z wywołaniem:

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

Począwszy od interfejsu API 21, należy getDrawable(int, Theme)zamiast tego użyć metody getDrawable(int), ponieważ pozwala ona pobrać obiekt do rysowania powiązany z określonym identyfikatorem zasobu dla danej gęstości ekranu / motywu. Wywołanie przestarzałej getDrawable(int)metody jest równoważne z wywołaniem getDrawable(int, null).


8
Myślę, że OP odnosi się również do getDrawable (int id)metody Contextklasy. Jest to to samo, co getResources().getDrawable(id, getTheme());nowy interfejs API.
kod małpa

9
Zgodnie z dokumentacją wymagany jest minimalny poziom API 21 getDrawable(int, Resources.Theme).
Książę

@Prince Metodę dodano do API 21, ale nie była przestarzała aż do API 22. :)
Alex Lockwood

Dokument Android zaleca również używanie Dokument systemu Context :: getDrawable (int), ale ponieważ została wprowadzona tylko w API 21, wydaje się, że ContextCompat jest najlepszym wyborem.
goRGon

Ta odpowiedź nie działa z plikami .svg w wersjach starszych niż API 21. W bibliotece jest błąd.
Jorge Rodríguez,

141

Zamień ten wiersz: getResources().getDrawable(R.drawable.your_drawable)

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

EDYTOWAĆ

ResourcesCompatjest teraz przestarzałe. Ale możesz użyć tego:

ContextCompat.getDrawable(this, R.drawable.your_drawable) (Tutaj this kontekst)

Aby uzyskać więcej informacji, kliknij ten link: ContextCompat




2
W linku nieResourcesCompat jest napisane, że jest przestarzałe. Powinno działać dobrze.
Jacob R

co napisać w „twoją możliwą do rysowania”, jeśli chcę wprowadzić obrazy do widoku listy po kliknięciu elementów listy przechowywanych w drawable
0x0001

29

getResources().getDrawable() był przestarzały na poziomie API 22. Teraz musimy dodać motyw:

getDrawable (int id, motyw Resources.Theme) (Dodano w interfejsie API na poziomie 21)

To jest przykład:

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

Oto przykład sprawdzania poprawności dla późniejszych wersji:

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, więc nie powinno to być if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)lub if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)? Nieważne. Od dołu „Metoda została dodana w API 21, ale nie była przestarzała aż do API 22. :)”
Mark Cramer

2

Możesz użyć

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

to dla mnie praca


Użycie kontekstu aplikacji do załadowania zawieszalnych rysunków wektorowych na pre Lollipop. Jakaś naprawa tego?
muthuraj,

1
@muthuraj Nie pamiętam moich testów dla kodu w przypadku Lollipop, ale zamiast tego możesz wypróbować getActivity () lub getResources (), czy to pasuje do twojego kodu?
Dasser Basyouni

Używam wzorca MVVM i muszę nadmuchać drawables wewnątrz ViewModels, które nie mają kontekstu aktywności. Ma tylko kontekst aplikacji. To jest mój problem.
muthuraj

1

To tylko przykład, jak naprawiłem problem w tablicy, aby załadować listView, mam nadzieję, że to pomoże.

 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

Spróbuj tego:

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

Chociaż ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, dlaczego i / lub jak ten kod odpowiada na pytanie, poprawia jego długoterminową wartość.
Kaczor Donald


1

getDrawable (int drawable) jest nieaktualny na poziomie API 22. W celach informacyjnych patrz ten link .

Teraz, aby rozwiązać ten problem, musimy przekazać nowy konstruktor wraz z identyfikatorem, takim jak: -

getDrawable(int id, Resources.Theme theme)

Dla rozwiązań Wykonaj następujące czynności: -

W Javie: -

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

lub

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

W Kotlinie: -

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

lub

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

Mam nadzieję, że to ci pomoże.


Warto wspomnieć, że getDrawable (DrawableRes int id, motyw Theme) może zgłosić wyjątek, jeśli zasób nie zostanie znaleziony, podczas gdy getDrawable (kontekst kontekstowy, int id) jest zerowy, więc należy go zwrócić z Drawable? w Kotlinie.
Pitos

0

en api poziom 14

marker.setIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.miubicacion, null));

Powinieneś podać nieco więcej kontekstu wokół swojej odpowiedzi.
Nicolas Grenié

0

Teraz musisz wdrożyć w ten sposób

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

Wystarczy jeden wiersz kodu, wszystko zajmie się ContextCompat.getDrawable

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

0

Dla niektórych, którzy wciąż rozwiązują ten problem, nawet po zastosowaniu sugestii tego wątku (kiedyś taki byłem), dodaj ten wiersz do klasy aplikacji, metoda onCreate ()

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

Jak sugerowano tu i tutaj, czasami jest to wymagane, aby uzyskać dostęp do wektorów z zasobów, szczególnie gdy masz do czynienia z elementami menu itp


0

W Kotlin możesz użyć rozszerzenia

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

    return  ContextCompat.getDrawable(this, id)
}

następnie użyj like

context.getMyDrawable(R.drawable.my_icon)

-2

Build.VERSION_CODES.LOLLIPOP należy teraz zmienić na BuildVersionCodes.Lollipop, tj .:

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

Czy BuildVersionCodesklasa nie jest specyficzna dla Xamarin?
Ted Hopp,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.