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

Resuelto DuyguK asked hace 54 años • 3 respuestas

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

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

¿Alguien puede corregirme?

DuyguK avatar Jan 01 '70 08:01 DuyguK
Aceptado

idDescripción general de Android

Un Android ides un número entero comúnmente utilizado para identificar vistas; esto idse puede asignar mediante XML (cuando sea posible) y mediante código (mediante programación). Es idmás útil para obtener referencias de Viewmensajes de correo definidos en XML generados por un Inflater(como mediante el uso de setContentView.)

Asignar idvíaXML

  • Agregue un atributo de android:id="@+id/algún nombre "a su vista.
  • Cuando se cree su aplicación, se le android:idasignará un código único int para su uso en el código.
  • Haga referencia a su android:idvalor inten el código usando " R.id.algún nombre" (efectivamente, una constante).
  • esto intpuede cambiar de una compilación a otra , así que nunca copie una identificación de gen/package.name/ R.java, solo use " R.id.somename".
  • (Además, un idasignado a un PreferenceXML no se utiliza cuando Preferencegenera su View).

Asignar idmediante código (programáticamente)

  • Establecer s manualmente idusando someView.setId(int);
  • Debe intser positivo, pero por lo demás es arbitrario: puede ser lo que quieras (sigue leyendo si esto te da miedo).
  • Por ejemplo, si crea y numera varias vistas que representan artículos, puede usar su número de artículo.

Unicidad de ids

  • XML-los s asignados idserán únicos.
  • Los mensajes de correo electrónico asignados idno tienen que ser únicos
  • Los s asignados por código idpueden (teóricamente) entrar en conflicto con los s XMLasignados id.
  • Estos idmensajes de correo electrónico en conflicto no importarán si se consultan correctamente (siga leyendo) .

Cuándo (y por qué) los mensajes conflictivos idno importan

  • findViewById(int)iterará primero en profundidad de forma recursiva a través de la jerarquía de vistas desde la Vista que especifique y devolverá la primera Viewque encuentre con una coincidencia id.
  • Siempre que no haya códigos asignados idantes de un XML definido iden la jerarquía, findViewById(R.id.somename)siempre devolverá la Vista definida por XML así id.

Crear vistas y asignar IDdinámicamente

  • En el diseño XML, defina un vacío ViewGroupcon id.
  • Como por ejemplo LinearLayoutcon android:id="@+id/placeholder".
  • Utilice código para completar el marcador de posición ViewGroupcon Views.
  • Si lo necesita o lo desea, asigne los correos electrónicos idque sean convenientes para cada vista.
  • Consulta estas vistas secundarias usando placeholder.findViewById(convenientInt);

  • Se introdujo API 17 View.generateViewId()que le permite generar una identificación única.

Si elige mantener las referencias a sus vistas , asegúrese de crear instancias de ellas getApplicationContext()y asegúrese de establecer cada referencia como nula en onDestroy. Aparentemente , filtrar el Activity(colgarlo después de destruirlo) es un desperdicio... :)

Reserve un XML android:idpara usarlo en el código

Se introdujo API 17 View.generateViewId() que genera una identificación única. (Gracias a take-chances-make-changes por señalar esto).*

Si ViewGroupno se puede definir a través de XML (o no desea que lo sea), puede reservar la identificación a través de XML para asegurarse de que siga siendo única:

Aquí, value/ids.xml define una costumbre id:

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

Luego, una vez que se haya creado el ViewGroup o View, puede adjuntar la identificación personalizada

myViewGroup.setId(R.id.reservedNamedId);

idEjemplo contradictorio

Para mayor claridad a modo de ejemplo confuso, examinemos lo que sucede cuando hay un idconflicto detrás de escena.

diseño/midiseño.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 intvalor de 12 ..

A continuación, MyActivity.java define algunas vistas agregadas 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í placeholderque uno de nuestros nuevos TextViewtiene un puntaje idde 12! Pero esto no es realmente un problema si consultamos las vistas secundarias de los marcadores 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

CodeShane avatar Nov 05 '2012 22:11 CodeShane

Puedes usar el View.setId(integer)para esto. En XML, aunque esté configurando una identificación de cadena, esta se convierte en un número entero. Debido a esto, puede usar cualquier número entero (positivo) para agregar Views mediante programación.

Según Viewla documentación

No es necesario que el identificador sea único en la jerarquía de esta vista. El identificador debe ser un número positivo.

Por lo tanto, puede utilizar cualquier número entero positivo que desee, pero en este caso puede haber algunas vistas con identificaciones equivalentes. Si desea buscar alguna vista en la jerarquía, puede ser útil llamar a setTag con algunos objetos clave.

Créditos a esta respuesta .

Sander van't Veer avatar Dec 10 '2011 23:12 Sander van't Veer

Sí, puede llamar setId(value)a cualquier vista con cualquier valor entero (positivo) que desee y luego encontrarlo en el contenedor principal usando findViewById(value). Tenga en cuenta que es válido llamar setId()con el mismo valor para diferentes vistas hermanas, pero findViewById()solo devolverá la primera.

dmon avatar Dec 10 '2011 23:12 dmon