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.