studio resource recursos getresources android android-view android-resources findviewbyid android-identifiers

resource - recursos android studio



¿Cómo puedo asignar una ID a una vista mediante programación? (3)

En un archivo XML, podemos asignar una ID a una vista como android:id="@+id/something" y luego llamar a findViewById() , pero al crear una vista mediante programación, ¿cómo puedo asignar una ID?

Creo que setId() no es lo mismo que la asignación predeterminada. setId() es extra.

¿Alguien puede corregirme?


Visión general de Android id

Un id Android es un número entero comúnmente utilizado para identificar vistas; esta id se puede asignar a través de XML (cuando sea posible) y mediante código (mediante programación). La id es más útil para obtener referencias para View definidas en XML generadas por un Inflater (como mediante el uso de setContentView ).

Asignar id través de XML

  • Agregue un atributo de android:id="@+id/ somename " a su vista.
  • Cuando se crea su aplicación, a android:id se le asignará una int única para usar en el código.
  • R.id. referencia a su android:id int value en el código usando " R.id. somename" (efectivamente una constante).
  • esta int puede cambiar de una compilación a otra, así que nunca copies una id de gen/ package.name/ R.java , solo usa " R.id. somename".
  • (Además, una id asignada a una Preference en XML no se usa cuando la Preference genera su View ).

Asignar id por código (programáticamente)

  • Configure manualmente los id con someView.setId( int );
  • El int debe ser positivo, pero por lo demás arbitrario, puede ser lo que quieras (sigue leyendo si es espantoso).
  • Por ejemplo, si crea y numera varias vistas que representan elementos, puede usar su número de artículo.

Unicidad de id s

  • XML id asignación XML serán únicos.
  • Los id código asignado no tienen que ser únicos
  • Los id Asignados por código pueden (en teoría) entrar en conflicto con los id con asignación XML .
  • Estos id Conflictivos no importarán si se consultan correctamente (sigue leyendo) .

Cuándo (y por qué) las id conflictivas no importan

  • findViewById(int) repetirá en profundidad recursivamente a través de la jerarquía de vistas desde la vista que especifique y devolverá la primera View que encuentre con un id correspondiente.
  • Siempre que no haya id asignados por código asignados antes de una id definida por XML en la jerarquía, findViewById(R.id.somename) siempre devolverá la vista definida en XML así id ''d.

Creación dinámica de vistas y asignación de ID s

  • En el diseño XML, defina un ViewGroup vacío con id .
  • Tal como LinearLayout con android:id="@+id/placeholder" .
  • Use el código para llenar el marcador de posición ViewGroup con View s.
  • Si necesita o quiere, asigne cualquier id que sea conveniente para cada vista.
  • Consulte estas vistas secundarias usando placeholder.findViewById (convenientInt);

  • API 17 introdujo View.generateViewId() que le permite generar una ID única.

Si elige mantener referencias a sus puntos de vista , asegúrese de crear una instancia con getApplicationContext() y asegúrese de configurar cada referencia a null en onDestroy . Aparentemente, filtrar la Activity (colgarse de ella después de que se destruya) es un desperdicio ... :)

Reserve un android:id XML android:id para usar en el código

API 17 introdujo View.generateViewId() que genera una ID única. (Gracias a take-chance-make-changes para señalar esto). *

Si su ViewGroup no se puede definir a través de XML (o no lo desea), puede reservar el id. A través de XML para asegurarse de que siga siendo único:

Aquí, values ​​/ ids.xml define una id personalizada:

<?xml version="1.0" encoding="utf-8"?> <resources> <item name="reservedNamedId" type="id"/> </resources>

Luego, una vez que ViewGroup o View ha sido creado, puede adjuntar el ID personalizado

myViewGroup.setId(R.id.reservedNamedId);

Ejemplo de id conflictiva

Para mayor claridad a modo de ejemplo ofuscante, examinemos lo que sucede cuando hay un conflicto de id detrás de las escenas.

layout / mylayout.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/placeholder" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > </LinearLayout>

Para simular un conflicto, digamos que nuestra última compilación asignó R.id.placeholder ( @+id/placeholder ) un valor int de 12 ..

A continuación, MyActivity.java define algunas vistas de adiciones mediante programación (mediante código):

int placeholderId = R.id.placeholder; // placeholderId==12 // returns *placeholder* which has id==12: ViewGroup placeholder = (ViewGroup)this.findViewById(placeholderId); for (int i=0; i<20; i++){ TextView tv = new TextView(this.getApplicationContext()); // One new TextView will also be assigned an id==12: tv.setId(i); placeholder.addView(tv); }

¡Así que el placeholder y uno de nuestros nuevos TextView s tienen una id de 12! Pero esto no es realmente un problema si consultamos las vistas secundarias del marcador de posición:

// Will return a generated TextView: placeholder.findViewById(12); // Whereas this will return the ViewGroup *placeholder*; // as long as its R.id remains 12: Activity.this.findViewById(12);

*No es tan malo


Puede usar View.setId(integer) para esto. En el XML, aunque está configurando un Id. De cadena, esto se convierte en un número entero. Debido a esto, puede usar cualquier número entero (positivo) para las Views que agrega programáticamente.

De acuerdo con la documentación de View

El identificador no tiene que ser exclusivo en la jerarquía de esta vista. El identificador debe ser un número positivo.

Entonces puedes usar cualquier número entero positivo que te guste, pero en este caso puede haber algunas vistas con id equivalentes. Si desea buscar alguna vista en la jerarquía llamando a setTag con algunos objetos clave, puede ser útil.

Créditos a esta respuesta .


Sí, puede llamar a setId(value) en cualquier vista con cualquier valor entero (positivo) que le guste y luego encontrarlo en el contenedor principal utilizando findViewById(value) . Tenga en cuenta que es válido llamar a setId() con el mismo valor para diferentes vistas de hermanos, pero findViewById() devolverá solo el primero.