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?


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

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).


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


2
Isso é depricated agora também: plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBM
Xyaren


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

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


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

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

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

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ê.


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

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)

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.


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)

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

Não é BuildVersionCodesuma classe específica para o Xamarin?
Ted Hopp
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.