API reprovada do Android getResources (). GetDrawable () 22

699

Com a nova API do Android 22, getResources().getDrawable()agora está obsoleta. Agora, a melhor abordagem é usar apenas getDrawable().

O que mudou?

Blodhgard
fonte
Você poderia especificar sua pergunta? É certo que o método getDrawable (int id)da classe Resourcesfoi descontinuado. Agora você deve usar o método getDrawable (int id, Resources.Theme theme)com o novo parâmetro de tema.
code monkey
1
ContextCompat.getDrawable (context, R.color.color_name)
Ashokchakravarthi Nagarajan
Você pode conferir o meu blog sobre este assunto para uma explicação mais completa sobre o porquê de tanto Resources#getDrawable(int)e Resources#getColor(int)foram obsoleto.
Alex Lockwood
1
O Google deve colocar correções rápidas para cada função reprovada. Fiz um post sobre isso aqui: code.google.com/p/android/issues/detail?id=219495
desenvolvedor Android

Respostas:

1027

Você tem algumas opções para lidar com essa depreciação da maneira certa (e à prova de futuro ), dependendo do tipo de drawable que você está carregando:


A) desenháveis com atributos de tema

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

Você obterá um Drawable com estilo conforme instruído pelo tema Atividade. Provavelmente é isso que você precisa.


B) desenháveis sem atributos de tema

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

Você terá seu drawable sem estilo da maneira antiga. Observe: nãoResourcesCompat.getDrawable() está obsoleto!


EXTRA) desenháveis com atributos de tema de outro tema

ResourcesCompat.getDrawable(getResources(), R.drawable.name, anotherTheme);
araks
fonte
Meu aplicativo trava usando a sugestão B. Ele não gosta da chamada Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null);
FractalBob 29/05
Declaro-o desta maneira: public static void setImageButtonEnabled (Contexto ctxt, booleano ativado, item ImageButton, int iconResId) {item.setEnabled (ativado); Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null); Ícone do Drawable = ativado? originalIcon: convertDrawableToGrayScale (originalIcon); item.setImageDrawable (ícone); } e chame assim: Utility.setImageButtonEnabled (getContext (), false, back, R.drawable.arrow_left);
FractalBob 29/05
Mais precisamente, o acidente parece estar acontecendo porque meu ícone é um vetor Drawable.
FractalBob 29/05
1
versão xamarin: ResourcesCompat.GetDrawable (Resources, Resource.Drawable.name, null);
Brian
Acrescento mais uma palavra para você, ContextCompat.getColor (contexto, cor) também pode ajudá-lo ...
BertKing
746

Editar: veja meu blog sobre o assunto para uma explicação mais completa


Você deve usar o seguinte código da biblioteca de suporte:

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

Usar este método é equivalente a chamar:

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

A partir da API 21, você deve usar o getDrawable(int, Theme)método em vez de getDrawable(int), pois permite buscar um objeto extraível associado a um ID de recurso específico para a densidade / tema da tela. Chamar o getDrawable(int)método descontinuado é equivalente a chamar getDrawable(int, null).

Alex Lockwood
fonte
8
Eu acho que o OP também se refere ao getDrawable (int id)método da Contextclasse. É o mesmo que getResources().getDrawable(id, getTheme());e também usa a nova API.
code monkey
9
De acordo com a documentação, é necessário usar o nível mínimo 21 da API getDrawable(int, Resources.Theme).
Prince
@Prince O método foi adicionado na API 21, mas não foi depreciado até API 22. :)
Alex Lockwood
O documento do Android também recomenda o uso do método Context :: getDrawable (int), mas, como foi introduzido apenas na API 21, parece que o ContextCompat é a melhor opção.
precisa saber é
Esta resposta não funciona com arquivos .svg, em versões anteriores à API 21. Há um erro na biblioteca.
Jorge Rodríguez
141

Substitua esta linha: getResources().getDrawable(R.drawable.your_drawable)

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

EDITAR

ResourcesCompattambém está obsoleto agora. Mas você pode usar isso:

ContextCompat.getDrawable(this, R.drawable.your_drawable)(Aqui thisestá o contexto)

para mais detalhes, siga este link: ContextCompat

vincent091
fonte
2
Isso é depricated agora também: plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBM
Xyaren
veja este link, por favor: developer.android.com/reference/android/support/v4/content/... , int)
vincent091
2
Não diz no link que ResourcesCompatestá obsoleto. Deve funcionar bem.
Jacob R
O que escrever no "seu drawable" se eu quiser imagens de entrada para uma exibição de lista clicando sobre os itens da lista armazenados em drawable
0x0001
29

getResources().getDrawable() foi descontinuado no nível 22 da API. Agora, devemos adicionar o tema:

getDrawable (identificação int, tema Resources.Theme) (adicionado no nível 21 da API)

Isto é um exemplo:

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

Este é um exemplo de como validar para versões posteriores:

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
fonte
Build.VERSION_CODES.LOLLIPOP is API 21, então não deveria ser if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)ou if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)? Deixa pra lá. From below "O método foi adicionado na API 21, mas não foi preterido até a API 22. :)"
Mark Cramer
2

Você pode usar

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

isso é trabalho para mim

Dasser Basyouni
fonte
Usando o contexto do aplicativo para carregar falhas de desenho vetorial no pré-pirulito. Alguma correção para isso?
93018 muthuraj # 07
1
@muthuraj Não me lembro dos meus testes para o código com caso pirulito, mas você pode tentar getActivity () ou getResources () em vez disso, isso vai bem com o seu código?
Dasser Basyouni
Estou usando o padrão MVVM e preciso aumentar os drawables dentro do ViewModels que não possuem contexto de atividade. Ele possui apenas o contexto do aplicativo. Esse é o meu problema.
muthuraj
1

Apenas um exemplo de como corrigi o problema em uma matriz para carregar um listView, espero que ajude.

 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)));
Jay
fonte
1

Tente o seguinte:

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));
    }
}
syakirin mohd nem
fonte
Embora esse código possa responder à pergunta, fornecer um contexto adicional a respeito de por que e / ou como esse código responde à pergunta melhora seu valor a longo prazo.
Donald Duck
1

Se você estiver segmentando SDK> 21 (pirulito ou 5.0), use

context.getDrawable(R.drawable.your_drawable_name)

Veja documentos

Adeel Ahmad
fonte
1

getDrawable (int drawable) foi descontinuado no nível 22 da API. Para obter referência, consulte este link .

Agora, para resolver esse problema, temos que passar um novo construtor junto com o id como: -

getDrawable(int id, Resources.Theme theme)

Para soluções Faça o seguinte: -

Em Java: -

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

ou

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

Em Kotlin: -

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

ou

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

Espero que isso ajude você.

Rahul Kushwaha
fonte
Vale ressaltar, que getDrawable (DrawableRes int id, Theme theme) pode lançar uma exceção se o recurso não for encontrado enquanto getDrawable (Contexto do contexto, int id) for anulável, portanto, ele deve ser retornado com Drawable? em Kotlin.
Pitos
0

en api nível 14

marker.setIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.miubicacion, null));
Jaime López Romero
fonte
Você deve fornecer um pouco mais de contexto em torno de sua resposta.
Nicolas Grenié
0

Agora você precisa implementar assim

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

Seguir uma única linha de código é suficiente, tudo será tratado por ContextCompat.getDrawable

ContextCompat.getDrawable(this, R.drawable.your_drawable_file)
Farid Haq
fonte
0

Para alguns que ainda resolveram esse problema, mesmo depois de aplicar a sugestão desse segmento (eu costumava ser um desses), adicione esta linha na classe Application, no método onCreate ()

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

Conforme sugerido aqui e aqui, às vezes isso é necessário para acessar vetores de recursos, especialmente quando você está lidando com itens de menu, etc.

Stamatis Stiliats
fonte
0

No Kotlin você pode usar a extensão

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

    return  ContextCompat.getDrawable(this, id)
}

então use como

context.getMyDrawable(R.drawable.my_icon)
Deepak Kanyan
fonte
-2

Agora Build.VERSION_CODES.LOLLIPOP deve ser alterado para BuildVersionCodes.Lollipop, ou seja:

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);
}
Ryan Herman
fonte
Não é BuildVersionCodesuma classe específica para o Xamarin?
Ted Hopp