Android getResources (). GetDrawable () en desuso API 22


699

Con el nuevo Android API 22 getResources().getDrawable()ahora está en desuso. Ahora el mejor enfoque es usar solo getDrawable().

¿Qué cambió?


¿Podría especificar su pregunta? Es cierto que el método getDrawable (int id)de la clase Resourcesestá en desuso. Ahora debe usar el método getDrawable (int id, Resources.Theme theme)con el nuevo parámetro de tema.
código mono

1
ContextCompat.getDrawable (contexto, R.color.color_name)
Ashokchakravarthi Nagarajan

Puede consultar la publicación de mi blog sobre este tema para obtener una explicación más detallada sobre por qué ambos Resources#getDrawable(int)y en Resources#getColor(int)desuso.
Alex Lockwood

1
Google debería poner soluciones rápidas para cada función en desuso. Hice una publicación al respecto aquí: code.google.com/p/android/issues/detail?id=219495
desarrollador de Android

Respuestas:


1027

Tiene algunas opciones para manejar este desuso de la manera correcta (y a prueba de futuro ), dependiendo del tipo de dibujo que esté cargando:


A) dibujables con atributos de tema

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

Obtendrá un Drawable con estilo según lo indique su tema de Actividad. Esto es probablemente lo que necesitas.


B) dibujables sin atributos de tema

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

Obtendrá su dibujable sin estilo a la antigua usanza. Tenga en cuenta: noResourcesCompat.getDrawable() está en desuso!


EXTRA) dibujables con atributos de tema de otro tema

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

Mi aplicación falla debido a la sugerencia B. No le gusta la llamada Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null);
FractalBob

Lo declaro de esta manera: public static void setImageButtonEnabled (contexto ctxt, booleano habilitado, elemento ImageButton, int iconResId) {item.setEnabled (habilitado); Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null); Icono dibujable = ¿habilitado? originalIcon: convertDrawableToGrayScale (originalIcon); item.setImageDrawable (icono); } y llámalo así: Utility.setImageButtonEnabled (getContext (), false, back, R.drawable.arrow_left);
FractalBob

Más precisamente, el bloqueo parece estar sucediendo porque mi ícono es un Vector dibujable.
FractalBob

1
versión de xamarin: ResourcesCompat.GetDrawable (Resources, Resource.Drawable.name, null);
Brian

Le agrego una palabra más, ContextCompat.getColor (contexto, color) también puede ayudarlo ...
BertKing

746

Editar: vea mi publicación de blog sobre el tema para obtener una explicación más completa


En su lugar, debe usar el siguiente código de la biblioteca de soporte:

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

Usar este método es equivalente a llamar:

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

A partir de API 21, debe usar el getDrawable(int, Theme)método en lugar de getDrawable(int), ya que le permite obtener un objeto dibujable asociado con un ID de recurso particular para la densidad / tema de pantalla dada. Llamar al getDrawable(int)método en desuso es equivalente a llamar getDrawable(int, null).


8
Creo que el OP también se refiere al getDrawable (int id)método de la Contextclase. Esto es lo mismo getResources().getDrawable(id, getTheme());y también usa la nueva API.
código mono

99
De acuerdo con la documentación, se requiere un nivel mínimo de API 21 para usar getDrawable(int, Resources.Theme).
Príncipe

@Prince El método se agregó en la API 21, pero no quedó en desuso hasta la API 22. :)
Alex Lockwood

El documento de Android también recomienda usar el método Context :: getDrawable (int), pero dado que se introdujo solo en API 21, parece que ContextCompat es la mejor opción.
goRGon

Esta respuesta no funciona con archivos .svg, en versiones anteriores a la API 21. Hay un error en la biblioteca.
Jorge Rodríguez

141

Reemplace esta línea: getResources().getDrawable(R.drawable.your_drawable)

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

EDITAR

ResourcesCompatTambién está en desuso ahora. Pero puedes usar esto:

ContextCompat.getDrawable(this, R.drawable.your_drawable)(Aquí thisestá el contexto)

para más detalles siga este enlace: ContextCompat




2
No dice en el enlace que ResourcesCompatestá en desuso. Debería funcionar bien.
Jacob R

qué escribir en "su dibujable" si quiero ingresar imágenes a una vista de lista al hacer clic en los elementos de la lista almacenados en
dibujable

29

getResources().getDrawable() quedó en desuso en el nivel 22 de API. Ahora debemos agregar el tema:

getDrawable (int id, Resources.Theme theme) (Agregado en API nivel 21)

Esto es un ejemplo:

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

Este es un ejemplo de cómo validar para versiones 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 21Entonces, ¿no debería ser esto if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)o if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)? No importa. Desde abajo "El método se agregó en la API 21 pero no se desactivó hasta la API 22. :)"
Mark Cramer

2

Puedes usar

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

eso es trabajo para mi


Uso del contexto de la aplicación para cargar bloqueos dibujables de vectores en pre lollipop. ¿Alguna solución para esto?
muthuraj

1
@muthuraj No recuerdo mi prueba para el código con el caso de lollipop, pero puede intentar obtener getActivity () o getResources () en su lugar, ¿eso va bien con su código?
Dasser Basyouni

Estoy usando el patrón MVVM y necesito inflar dibujables dentro de ViewModels que no tienen contexto de actividad. Solo tiene contexto de aplicación. Ese es mi problema.
muthuraj

1

Solo un ejemplo de cómo solucioné el problema en una matriz para cargar una vista de lista, espero que ayude.

 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

Prueba esto:

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

Si bien este código puede responder la pregunta, proporcionar un contexto adicional con respecto a por qué y / o cómo responde la pregunta mejora su valor a largo plazo.
Pato Donald


1

getDrawable (int drawable) está en desuso en el nivel 22 de API. Para referencia, consulte este enlace .

Ahora para resolver este problema, tenemos que pasar un nuevo constructor junto con una identificación como la siguiente:

getDrawable(int id, Resources.Theme theme)

Para soluciones Haga esto: -

En Java: -

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

o

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

En Kotlin: -

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

o

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

Espero que esto te ayude. Gracias.


Vale la pena mencionar que getDrawable (DrawableRes int id, Theme theme) puede lanzar una excepción si no se encuentra el recurso mientras que getDrawable (Context context, int id) es anulable, por lo que debe devolverse con Drawable. en Kotlin
Pitos

0

en api nivel 14

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

Debería proporcionar un poco más de contexto en torno a su respuesta.
Nicolas Grenié

0

Ahora necesitas implementar así

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

Seguir una sola línea de código es suficiente, ContextCompat.getDrawable se encargará de todo.

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

0

Para algunos que todavía tienen que resolver este problema incluso después de aplicar la sugerencia de este hilo (solía ser uno como ese), agregue esta línea en su clase de Aplicación, método onCreate ()

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

Como se sugiere aquí y aquí, a veces esto es necesario para acceder a los vectores de los recursos, especialmente cuando se trata de elementos de menú, etc.


0

En Kotlin puedes usar extensión

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

    return  ContextCompat.getDrawable(this, id)
}

luego usar como

context.getMyDrawable(R.drawable.my_icon)

-2

Build.VERSION_CODES.LOLLIPOP ahora debería cambiarse a BuildVersionCodes.Lollipop, es decir:

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

¿No es BuildVersionCodesuna clase específica de Xamarin?
Ted Hopp
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.