usesupportlibrary - vector drawable android
¿Cómo usar vectores arrastrables con Vista además de ImageView con srcCompat? (8)
app:srcCompat
con ImageView
permite el uso compatible con versiones anteriores de vectores dibujables. Pero, ¿cómo puedes usarlos con otras View
además de ImageView
? Por ejemplo, los atributos TextView
como android:drawableLeft
.
También utilizando el vector dibujable como un android:icon
MenuItem
provocó un bloqueo con la siguiente excepción:
Fatal Exception: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:626)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:702)
at android.view.LayoutInflater.inflate(LayoutInflater.java:470)
at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
at android.support.v7.view.menu.MenuItemImpl.setActionView(MenuItemImpl.java:621)
at android.support.v7.view.menu.MenuItemImpl.setActionView(MenuItemImpl.java:40)
at android.support.v4.view.MenuItemCompat.setActionView(MenuItemCompat.java:310)
at android.support.v7.view.SupportMenuInflater$MenuState.setItem(SupportMenuInflater.java:465)
at android.support.v7.view.SupportMenuInflater$MenuState.addItem(SupportMenuInflater.java:479)
at android.support.v7.view.SupportMenuInflater.parseMenu(SupportMenuInflater.java:196)
at android.support.v7.view.SupportMenuInflater.inflate(SupportMenuInflater.java:118)
at com.example.niceapp.context.main.MainActivity.onCreateOptionsMenu(MainActivity.java:101)
at android.app.Activity.onCreatePanelMenu(Activity.java:2578)
Con Support Library 23.2.0, ¿cómo se puede abordar este problema?
Android 5.0 (API nivel 21) y superior proporciona compatibilidad con vectores dibujables. Si su aplicación tiene un nivel mínimo de API que es más bajo, Vector Asset Studio agrega el archivo dibujable del vector a su proyecto; Además, en tiempo de compilación, Gradle crea imágenes ráster PNG en varias resoluciones. Gradle genera las densidades PNG especificadas por la propiedadDynamiesDLL (lenguaje específico de dominio) en un archivo build.gradle. Para generar PNG, el sistema de compilación requiere Android Plugin para Gradle 1.5.0 o superior.
Esto no es cierto si incluye en su vector gradleDrawables.useSupportLibrary = true
ya sea configurado en falso o eliminar la línea por completo y todos sus vectores funcionarán como estaban. Pero para las versiones antiguas de Android, podrán confiar en el PNG convertido
Dadou tiene razón Entonces, si desea usar el selector para ver con VectorDrawables, debe agregar:
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(trfor);
}
a cada actividad en la que desee usar VectorDrawables en dispositivos con versiones inferiores a Android 5.
Estoy usando una nueva biblioteca de soporte y todo lo que tengo que hacer es:
compile ''com.android.support:appcompat-v7:25.1.1''
En el archivo Build.gradle
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
Ahora, donde sea que estés usando fragmentos, actividades o adaptadores, utiliza esto como la primera línea de tu clase
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
después de eso, use como lo hacemos antes, something.xml
<ImageView
android:id="@+id/ivMainNavigationIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Algo.java
thumbIcon.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.ic_check_circle_black_24dp));
o si tiene una ID dibujable que se debe configurar dinámicamente
thumbIcon.setImageDrawable(ContextCompat.getDrawable(context,drawableID));
Form android studio 3.0.0 android: src no es compatible con la imagen vectorial y debajo de 21 mi get exception. utilizar la aplicación: srcCompat para la imagen vectorial. Mantenga todos los archivos de imagen vectorial dentro de la carpeta dibujable .
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Y en la clase de aplicación defina esto:
@Override
public void onCreate() {
super.onCreate();
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Ahora puedes usar tu archivo .xml. No olvides utilizar este enlace: xmlns: app = "http://schemas.android.com/apk/res-auto"
<RelativeLayout
android:id="@+id/counterValuePanel"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_cart_notify"/>
</RelativeLayout>
Ahora puedes usar la aplicación: srcCompat = "@ drawable / ic_cart_notify" pero si tratas de usar en android: background o android: drawableLeft tienes la excepción "Error inflating". Para eso crea un nuevo archivo empateable .xml, ic_cart_notify es un icono de vector.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_cart_notify"/>
</layer-list>
Para la versión 23.3.0 de AppCompat donde no hay solución de trabajo a través del selector XML (respuesta aceptada de razzledazzle), podemos hacer esto mediante programación:
activity_main.xml
<android.support.v7.widget.AppCompatImageButton
android:id="@+id/btnEnter"
/>
MainActivity.java
AppCompatImageButton image = (AppCompatImageButton) findViewById(R.id.btnEnter);
if (image != null) {
VectorDrawableCompat vcAccept = VectorDrawableCompat.create(getResources(), R.drawable.vc_accept, getTheme());
VectorDrawableCompat vcAcceptWhite = VectorDrawableCompat.create(getResources(), R.drawable.vc_accept_white, getTheme());
StateListDrawable stateList = new StateListDrawable();
stateList.addState(new int[]{android.R.attr.state_focused, -android.R.attr.state_pressed}, vcAccept);
stateList.addState(new int[]{android.R.attr.state_focused, android.R.attr.state_pressed}, vcAcceptWhite);
stateList.addState(new int[]{-android.R.attr.state_focused, android.R.attr.state_pressed}, vcAcceptWhite);
stateList.addState(new int[]{}, vcAccept);
image.setImageDrawable(stateList);
}
Este código es equivalente para este selector xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/vc_accept" />
<item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/vc_accept_white" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/vc_accept_white" />
<item android:drawable="@drawable/vc_accept" />
</selector>
ACTUALIZAR
Si el vector dibujable no se muestra con API 23, primero Drawable
convertir el VectorDrawable
a Drawable
normal. Si desea usar setCompoundDrawablesWithIntrinsicBounds
, tendrá que hacer esto, pero para StateListDrawable no era necesario.
Drawable icon;
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
icon = VectorDrawableCompat.create(getResources(), R.drawable.vc_icon, getContext().getTheme());
} else {
icon = getResources().getDrawable(R.drawable.vc_icon, getContext().getTheme());
}
Puede agregar Vector Drawable en TextView mediante programación. Utilice VectorDrawableCompat para agregar drawableLeft / drawableRight / drawableTop / drawableBottom / drawableStart / drawableEnd.
Pasos:
yo. Si TextView está dentro de la actividad:
TextView tvUserName= (TextView)findViewById(R.id.et_username_or_email);
VectorDrawableCompat drawableCompat=VectorDrawableCompat.create(getResources(), R.drawable.layer_list_ic_user, tvUserName.getContext().getTheme());
tvUserName.setCompoundDrawablesRelativeWithIntrinsicBounds(drawableCompat, null, null, null);
ii. Si TextView está dentro de Fragment:
TextView tvUserName= (TextView )view.findViewById(R.id.et_username_or_email);
VectorDrawableCompat drawableCompat=VectorDrawableCompat.create(getActivity().getResources(), R.drawable.layer_list_ic_user, tvUserName.getContext().getTheme());
tvUserName.setCompoundDrawablesRelativeWithIntrinsicBounds(drawableCompat, null, null, null);
Para obtener más información sobre VectorDrawableCompat, consulte este link
Actualización 2 : Han agregado una opción para habilitarlo nuevamente en la Biblioteca de soporte 23.4.0:
Para los usuarios de AppCompat, hemos agregado una API opcional para volver a habilitar la compatibilidad de Vector Drawables con los recursos (el comportamiento encontrado en 23.2) a través de AppCompatDelegate.setCompatVectorFromResourcesEnabled() : tenga en cuenta que esto puede causar problemas con el uso y el uso de la memoria Actualizando instancias de configuración, por lo tanto, por qué está deshabilitado de forma predeterminada.
Actualización : Esto ya no funciona a partir de la versión 23.3.0
Para los usuarios de AppCompat, hemos decidido eliminar la funcionalidad que le permite utilizar vectores arrastrables de recursos en dispositivos anteriores a Lollipop debido a problemas encontrados en la implementación en la versión 23.2.0 / 23.2.1 [ https://code.google.com/p/android/issues/detail?id=205236 , https://code.google.com/p/android/issues/detail?id=204708] . Uso de la aplicación: srcCompat y setImageResource () continúa funcionando.
De los desarrolladores de Android publicación de Google+
Uso de AppCompat y la aplicación: srcCompat es el método más infalible para integrar vectores arrastrables en su aplicación.
Esa cita es del blogpost oficial para el lanzamiento de la versión 23.2.0 de la Biblioteca de soporte.
La publicación también menciona lo siguiente:
Encontrará referencia directa a los vectores arrastrables fuera de la
app:srcCompat
fallará antes de Lollipop. Sin embargo,AppCompat
es compatible con la carga de vectores arrastrables cuando se hace referencia a ellos en otro contenedorStateListDrawable
comoStateListDrawable
,InsetDrawable
,LayerDrawable
,LevelListDrawable
yRotateDrawable
. Al usar esteTextView
indirecto, puede utilizar vectores arrastrables en casos como elTextView
android:drawableLeft
TextView
deTextView
, que normalmente no sería compatible con vectores dibujables.
Esto se traduce en los siguientes pasos:
Paso 1:
Crea o importa un recurso vectorial que necesites para la aplicación. Por ejemplo, uno puede crear un vector dibujable para el ícono de búsqueda y nombrarlo ic_action_search_vector.xml
Paso 2:
Cree otro recurso dibujable de proxy para el vector dibujable creado previamente. Digamos, para el ic_action_search_vector.xml
anterior, ic_action_search.xml
se puede crear como un simple StateListDrawable
que podría contener las siguientes líneas:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_action_search_vector"/>
</selector>
Este paso se puede omitir si ha hecho referencia al vector dibujable desde otro recurso dibujable que utilizará con su Vista.
Paso 3:
Utilice el recurso ic_action_search.xml
(aquí, ic_action_search.xml
) que se refiere al vector ic_action_search_vector.xml
( ic_action_search_vector.xml
) en lugar del vector dibujable directamente. Para un menú, se vería así:
<item android:id="@+id/search"
android:title="@string/search"
android:icon="@drawable/ic_action_search"
app:showAsAction="always"/>
¡Esta es la solución a ese problema!
Vector drawables se puede utilizar antes de Lollipop en otros lugares que no sea la app:srcCompat
, pero tiene un precio.
He creado este diagrama para ayudar (válido para Support Library 23.4.0 a, al menos, 25.1.0).