Cómo especificar la identificación cuando los usos se incluyen en el archivo xml de diseño

117

En mi archivo xml de diseño, he incluido otro archivo xml de diseño (cada uno con una identificación de Android diferente).

<include layout="@layout/view_contact_name" android:id="+id/test1"/>
<include layout="@layout/view_contact_name" android:id="+id/test2"/>

Pero cuando lo ejecuto en el emulador e inicio Hierarchy Viewer, cada uno de los diseños todavía muestra 'NO_ID', y en mi código, tengo findViewById(R.id.test1)y findViewById(R.id.test2)ambos devuelven nulo.

¿Alguien puede ayudarme con mi problema?

hap497
fuente
6
A sus identificaciones les falta el @símbolo.
AutonomousApps

Respuestas:

288

Especifique el ID en el <include>

<include layout="@layout/test" android:id="@+id/test1" />

Luego use dos findViewByIdpara acceder a los campos en el diseño

View test1View = findViewById(R.id.test1);
TextView test1TextView = (TextView) test1View.findViewById(R.id.text);

Con ese enfoque, puede acceder a cualquier campo en cualquier inclusión que tenga.

Ron Romero
fuente
18
Este método me devuelve un valor nulo para el objeto test1View.
Nirav Shah
4
Realmente no veo la diferencia, ¿puedes explicarme?
Goddchen
30
Descubrí que si el diseño que incluimos usa fusión, esto no ayudará. Pero en caso de que no se utilice la combinación, esto funciona.
Zlatko
@Zlatko Sí, y esto no puede funcionar mergeni siquiera en teoría, porque el resultado de incluir a mergeno es una vista única, sino un montón de ellas. Entonces está bien.
Nombre para mostrar
1
Esto solo funcionará en caso de que no se utilice la combinación. En caso de fusión, no es posible como se especifica aquí: code.google.com/p/android/issues/detail?id=36918#c3
Zahid Rasheed
61

Descubrí que si está utilizando una <merge>etiqueta en su diseño de inclusión, entonces el ID de inclusión se transfiere a la etiqueta de combinación, que no es una vista real.

Entonces, elimine la combinación o reemplácela con algún diseño.

Tor Norbye escribió :

La <include>etiqueta no es una vista real, por lo que findByView no la encontrará. En su lugar, el atributo @id (y cualquier otro atributo que haya establecido en la etiqueta de inclusión) se aplica en la etiqueta raíz del diseño incluido. Entonces, su activity.getView (R.id.included1) debería ser de hecho el <TextView>mismo.

loki19
fuente
3
Buena Elimino la etiqueta de combinación y comienza a funcionar, pero mi pregunta aquí es ¿cuál es el uso de la etiqueta de combinación si alguna incluye el diseño que funciona sin ella?
Ankur Chaudhary
35

Romain Guy indica que puede anular el ID de un diseño incluido colocando un android:idatributo dentro de la <include>etiqueta.

<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
Daniel Yankowsky
fuente
1
Esto es correcto. La forma de hacer referencia al elemento raíz en el archivo de diseño incluido es mediante la identificación proporcionada en la etiqueta 'incluir' (a menos que no se proporcione).
Tom R
1
ID en <include> = ID de root en el diseño incluido
Fadils
Me parece que si configuro la identificación primero (en la etiqueta de inclusión, anula la identificación del diseño incluido, ¿verdad?), Tendré que la etiqueta de inclusión sea inicialmente '@ + id / celda1' y luego el diseño = ' @ layout / workspace_screen 'anulará el android: id nuevamente con el id del diseño incluido. Las respuestas de @Ron Romero tienen más sentido para mí.
Neon Warge
14

Creo que la respuesta principal pasa por alto el punto más importante y podría inducir a error a las personas a pensar que la <include/>etiqueta crea una Vista que contiene los contenidos incluidos.

El punto clave es que el ID de inclusión se pasa a la vista raíz del archivo de diseño de inclusión.

Lo que significa que esto:

// activity_main.xml
<include layout="@layout/somelayout" android:id="@+id/someid"/>

// somelayout.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

Se convierte en esto:

// activity_main.xml
<ImageView
    android:id="@+id/someid"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />
André Romano
fuente
4

sí es así, pero tenga cuidado cuando el diseño insertado en el campo de inclusión es personalizado y desea acceder a ese diseño raíz. Ese diseño en este caso @ diseño / prueba de prueba, en realidad se devuelve en la primera línea.

test test1View = (test)findViewById(R.id.test1);
jokernk
fuente
2
  1. debe establecer la identificación de cada etiqueta de inclusión
  2. El elemento secundario incluido establece una nueva identificación. si busca cómo generar una nueva identificación, mire esta entrada: https://stackoverflow.com/a/15442898/1136117
Sinan Ergin
fuente
2

El problema es que intentamos usar una identificación que no está declarada en el archivo de diseño actual. En lugar de declarar nuevamente, id se puede simplemente referir usando @+id/. Si refactoriza el nombre de identificación original a través de Android Studio, también se refactoriza en el diseño incluido.

<include layout="@layout/toolbar"/>

<TextView
    android:id="@+id/txt_description"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    **android:layout_below="@+id/toolbar"**
    android:layout_marginTop="16dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"/>
Prakash
fuente
2

En el caso de usar, <RecyclerView>busque el id de <include>usando una instancia de vista inflada o de lo contrario devolverá nulo .

public class ViewHolder extends RecyclerView.ViewHolder {

        private mTextView;

        public ViewHolder(View view) {
            super(view);
            View include_1 = view.findViewById(R.id.include_1);
            mTextView = (TextView) include_1.findViewById(R.id.text_id);
        }
    }
Shanki Bansal
fuente
1

Si ha establecido id en cualquiera de las etiquetas raíz del diseño incluido, puede usar ese id o puede establecer el id en el diseño incluido.

Pero no puede establecer id en ambos, puede generar una excepción.

<include layout="@layout/view_contact_name" android:id="+id/test1"/>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

....
</LinearLayout>

O

<include layout="@layout/view_contact_name"/>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        android:id="@+id/llBottomMainView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

....
</LinearLayout>
Upendra Shah
fuente
0

Cuando se habla de inclusión, tiene una identificación en la vista raíz dentro del archivo de diseño incluido o en la línea de inclusión en sí y no en ambas. Por ejemplo:

<include layout="@layout/layout1" android:id="@+id/layout1"/>

Diseño 1 archivo

<RelativeLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layout2">

</RelativeLayout>

El ejemplo anterior es incorrecto porque técnicamente tiene dos identificaciones declaradas para el mismo diseño. Entonces, lo que tienes que hacer es elegir qué elemento tendrá la identificación.

mossman252
fuente
0

Vaya, no puedo creer que esta pregunta aún no tenga la respuesta correcta. Es simple, las etiquetas apestan. Solo puede cambiar las cosas que comienzan con las android:layout_que android:idno coinciden. Entonces la respuesta es que no puedes. Lo siento. Lo que puede hacer en su lugar es crear una clase que será un ViewGroup que inflará las vistas incluidas en el interior, luego agregará eso como una etiqueta en su diseño, pero eso es todo.

TheHebrewHammer
fuente