¿Cómo funciona "? Android: attr / selectedBackgroundIndicator"?

86

Estaba buscando cómo resaltar un elemento seleccionado en una lista al mostrar una barra de acción contextual para la selección, y la solución que encontré fue establecer el android:backgroundatributo de mi diseño de fila xml en "?android:attr/activatedBackgroundIndicator".

Sin embargo, ¿cómo funciona esta configuración?

  1. cual es el mecanismo involucrado?
  2. ¿Qué significan los elementos de sintaxis como "?", "attr", "activeBackgroundIndicator "?
  3. ¿Dónde se define el significado de "activeBackgroundIndicator "?
jrharshath
fuente

Respuestas:

221

Si está de humor forense, aquí le explicamos cómo investigar y averiguar qué está sucediendo.

android:background="?android:attr/activatedBackgroundIndicator"?

Intuitivamente, esto significa establecer el fondo en algún elemento de diseño.

Pero descompongamos esto aún más para ver cómo llegamos a nuestro misterioso dibujo.

Para ser precisos, significa "establecer el atributo de fondo a lo que se refiere el atributo" selectedBackgroundIndicator " en el tema actual .

Si entiende la parte de "se refiere al tema actual", básicamente ha entendido todo lo que sucede detrás de las portadas.

Básicamente , activeBackgroundIndicator no es un dibujable real sino una referencia a un dibujable . Entonces, ¿dónde está realmente definido el atributo "activeBackgroundIndictor "?

Está definido en su directorio sdk en un nombre de archivo attrs.xml . Por ejemplo:

ruta_a_android_sdk / plataformas / android-17 / data / res / values ​​/ attrs.xml

Si abre ese archivo, obtendrá la declaración de la siguiente manera:

<attr name="activatedBackgroundIndicator" format="reference" />

attrs.xml es donde declaras todos los atributos que luego usarás en tu vista xml. Tenga en cuenta que estamos declarando el atributo y su tipo y no asignando un valor aquí .

El valor real se asigna en themes.xml . Este archivo se encuentra en:

ruta_a_android_sdk / plataformas / android-17 / data / res / values ​​/ themes.xml

Si abre ese archivo, verá las múltiples definiciones según el tema que esté utilizando . Por ejemplo, aquí están las definiciones para el nombre de los temas Theme, Theme.Light, Theme.Holo, Theme.Holo.Light respectivamente:

<item name="activatedBackgroundIndicator">@android:drawable/activated_background</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_light</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_dark</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_light</item>

Ahora tenemos nuestros misteriosos dibujables. Si elige el primero, se define en la carpeta dibujable en:

ruta_a_android_sdk / plataformas / android-17 / data / res / drawable / selected_background.xml

Si abre ese archivo, verá la definición del dibujable, lo cual es importante para comprender lo que está sucediendo.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true" android:drawable="@android:drawable/list_selector_background_selected" />
    <item android:drawable="@color/transparent" />
</selector>

Aquí estamos definiendo un elemento de diseño con dos estados: el estado predeterminado es simplemente fondo transparente y si el estado es "state_activated", nuestro elemento de diseño es "list_selector_background_selected".

consulte este enlace para obtener información general sobre los elementos de diseño y los estados.

"list_selector_background_selected" es un archivo png de 9 parches que se encuentra en la carpeta drawable-hdpi.

Ahora puede ver por qué definimosactiveBackgroundIndicator como referencia en lugar de vincularlo directamente al archivo dibujable; le permite elegir el dibujable correcto según su tema.

numan salati
fuente
3
Una respuesta para gobernarlos a todos. Entonces, básicamente, si uno hiciera un XML con los mismos selectores, ¿podría crear su propio "activeBackgroundIndicator"?
Gee.E
1
exactamente: puede redefinirlo en su theme.xml personalizado b / c es un atributo de referencia.
numan salati
Esta respuesta me ayudó a descubrir cómo configurar un elemento de diseño personalizado en el elemento de la lista del cajón de navegación.
Tastybrownies
Este es un gran recurso para comenzar a trabajar en selectortrabajos personalizados utilizando elementos de diseño . Después de leer esto, utilicé Style Attribute Docs para completar las piezas restantes.
Maurizio
1
¿Puede proporcionar un ejemplo de cómo anular este indicador de fondo? El mío no funciona: / <style name = "AppTheme" parent = "Theme.AppCompat.Light.DarkActionBar"> <item name = "android: selectedBackgroundIndicator"> @ drawable / selected_background </item> </style> enabled_background.xml : <selector xmlns: android = " schemas.android.com/apk/res/android "> <elemento android: state_activated = "true" android: drawable = "@ color / yellow" /> <elemento android: drawable = "@ android: color / transparent "/> </selector>
vandus
13

También me pregunté esto en un momento. Una gran cantidad de recursos de Android parecen ser como una caja negra y no se pueden ver directamente. Es posible que me los pierda en algún lugar, pero no puedo encontrarlos en el código fuente del SDK. Esto es lo que sé.

  • android:background tomará un dibujable.
  • La sintaxis está en el estilo

    Debe ser una referencia a otro recurso, en la forma "@ [+] [paquete:] tipo: nombre" o a un atributo de tema en la forma "? [Paquete:] [tipo:] nombre"

En este caso, ?significa mirar un tema en el paquete androidy es del tipo attrdonde está el nombre activatedBackgroundIndicator.

También debería poder acceder a esto en el código subyacente con android.R.attr.activatedBackgroundIndicator.

attrPuede encontrar una lista de propiedades de Android en R.attr

  • activatedBackgroundIndicator es un dibujable definido en Android 3.0+ como

    Dibujable utilizado como fondo para elementos activados.

Básicamente es solo un elemento estándar definido en el sistema operativo. Parece que no puedo encontrarlo en la fuente de Android, pero aquí hay un enlace a la documentación. activadoBackgroundIndicator

Iglesia
fuente
5

Esta es una forma de asignar un valor a un tema. El valor no se conoce técnicamente durante la compilación de recursos porque es posible que los valores del tema no se conozcan en ese momento. En su lugar, el valor se resuelve en tiempo de ejecución según el tema real tomado de (más comúnmente) ContextThemeWrapper.

Esto proporciona una forma de reutilizar los valores de los recursos. No me refiero al rendimiento, sino a la organización y al mantenimiento. El atributo actúa como si fuera una variable con la promesa de que mantendrá un valor real en tiempo de ejecución.

Este enfoque también permite una mayor personalización: en lugar de codificar el valor de, por ejemplo, el elemento de diseño de fondo de la ventana, obtiene el elemento de diseño real de un tema, proporcionando un atributo elegido como clave. De este modo, se anula el valor para ese atributo. Simplemente necesitas:

  1. Cree su propio tema (que es solo un nombre elegante para un recurso de "estilo"), que generalmente se deriva de uno de los temas predeterminados.
  2. Proporcione su propio valor para el atributo en cuestión.

La plataforma utilizará automáticamente su valor siempre que haya especificado su tema para una actividad o aplicación. Haz esto como se describe en la pregunta. La sintaxis general de las referencias de atributos de tema se describe aquí: Atributos de estilo de referencia . Allí también encontrará un ejemplo y una descripción de todo el mecanismo.

Editar

Una cosa que debe tenerse en cuenta son los nombres de los atributos reales y su existencia en varias versiones de plataforma. Es bastante común que se introduzcan nuevos atributos en las próximas versiones de la plataforma; por ejemplo, algunos se agregaron en la versión 3.0 con el propósito de diseñar ActionBar.

Debe tratar los nombres de los atributos como parte de la API; en otras palabras, son parte del contrato que puede usar. Esto es muy similar a las clases y sus firmas: usa la LocationManagerclase con el propósito de obtener la ubicación del último dispositivo porque sabe de alguna fuente (tutoriales, referencias, guías oficiales, etc.) cuál es el propósito de esta clase. De manera similar, los nombres de los atributos y su propósito están (a veces bien, a veces miserablemente) definidos en la documentación de la plataforma Android.

andr
fuente
2

Actualización: hay una versión más detallada disponible en la Guía de API, así que me gustaría citarla.

Un recurso de atributo de estilo le permite hacer referencia al valor de un atributo en el tema aplicado actualmente. Hacer referencia a un atributo de estilo le permite personalizar el aspecto de los elementos de la IU diseñándolos para que coincidan con las variaciones estándar proporcionadas por el tema actual, en lugar de proporcionar un valor codificado. Hacer referencia a un atributo de estilo básicamente dice, "use el estilo que está definido por este atributo, en el tema actual".

Para hacer referencia a un atributo de estilo, la sintaxis del nombre es casi idéntica al formato de recurso normal, pero en lugar del símbolo arroba (@), use un signo de interrogación (?), Y la parte del tipo de recurso es opcional. Por ejemplo:

Respuesta original:

numan salati ya ofreció una respuesta perfecta pero no ha abordado el "?" sintaxis. Aquí hay una cita de la Guía de API Acceso a recursos

Para hacer referencia a un atributo de estilo, la sintaxis del nombre es casi idéntica al formato de recurso normal, pero en lugar del símbolo arroba (@), use un signo de interrogación (?), Y la parte del tipo de recurso es opcional. Por ejemplo:

? [<nombre_paquete>:] [<tipo_recurso> /] <nombre_recurso>

Teng-pao Yu
fuente