Como especificar id quando usa incluir no arquivo XML de layout

117

No meu arquivo xml de layout, incluí outro arquivo xml de layout (cada um com um id de Android diferente).

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

Mas quando eu o executo no emulador e inicio o Hierarchy Viewer, cada layout ainda mostra 'NO_ID', e no meu código, eu tenho findViewById(R.id.test1)e findViewById(R.id.test2)ambos retornam nulo.

Alguém pode me ajudar com meu problema?

Hap497
fonte
6
Seus IDs estão sem o @símbolo.
AutonomousApps de

Respostas:

288

Especifique o ID no <include>

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

Em seguida, use dois findViewByIdpara acessar os campos no layout

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

Usando essa abordagem, você pode acessar qualquer campo em qualquer include que tiver.

Ron Romero
fonte
18
Este método retorna um valor nulo para o objeto test1View.
Nirav Shah
4
Eu realmente não vejo a diferença, você pode explicar?
Goddchen
30
Descobri que, se o layout que incluímos estiver usando mesclagem, isso não ajudará. Mas no caso em que a fusão não é usada, isso funciona.
Zlatko
@Zlatko Sim, e isso não funciona mergenem em teoria, porque o resultado de incluir um mergenão é uma única visualização, mas um monte delas. Então está tudo bem.
Nome de exibição
1
Isso só funcionará caso a mesclagem não seja usada. Em caso de mesclagem, não é possível conforme especificado aqui: code.google.com/p/android/issues/detail?id=36918#c3
Zahid Rasheed
61

Eu descobri que se você estiver usando <merge> tag em seu layout de inclusão, o ID de inclusão é transferido para a tag de mesclagem que não é a visualização real.

Portanto, remova a fusão ou substitua-a por algum layout.

Tor Norbye escreveu :

A <include>tag não é uma visualização real, portanto, findByView não a encontrará. O atributo @id (e quaisquer outros atributos que você definiu na tag de inclusão) são aplicados na tag raiz do layout incluído. Portanto, seu activity.getView (R.id.included1) deve de fato ser o <TextView>próprio.

loki19
fonte
3
Um bom. Eu removo a tag de mesclagem e ela começa a funcionar, mas minha pergunta aqui é: qual é o uso da tag de mesclagem se algum incluir layout funcionando sem ela?
Ankur Chaudhary
35

Romain Guy indica que você pode substituir o ID de um layout incluído, colocando um android:idatributo dentro da <include>tag.

<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
Daniel Yankowsky
fonte
1
Isto está certo. A forma de referenciar o elemento raiz no arquivo de layout incluído é pelo id fornecido na tag 'include' (a menos que não seja fornecido).
Tom R de
1
ID em <include> = ID da raiz no layout incluído
Fadils
Parece-me que se eu definir o id primeiro (na tag de inclusão, ele substitui o id do layout incluído, certo?), Terei a tag de inclusão inicialmente '@ + id / cell1' e, em seguida, o layout = ' @ layout / workspace_screen 'substituirá o android: id novamente com o id do layout incluído. As respostas de @Ron Romero fazem mais sentido para mim.
Neon Warge
14

Acho que a resposta principal perde o ponto mais importante e pode induzir as pessoas a pensar que <include/> tag cria uma visualização que contém o conteúdo de inclusão.

O ponto principal é que o id de inclusão é passado para a visualização raiz do arquivo de layout do include.

O que significa que este:

// 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"
    />

Torna-se isto:

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

sim é assim, mas cuidado quando o layout inserido no campo de inclusão é personalizado e você deseja acessar esse layout raiz. Esse layout, neste caso @ layout / test test, é realmente retornado na primeira linha.

test test1View = (test)findViewById(R.id.test1);
Jokernk
fonte
2
  1. você deve definir o id de cada tag de inclusão
  2. elemento filho incluído define um novo id. se você olhar como gerar um novo id, veja esta entrada: https://stackoverflow.com/a/15442898/1136117
Sinan Ergin
fonte
2

O problema é que tentamos usar o id que não está declarado no arquivo de layout atual. Em vez de declarar novamente, id pode ser simplesmente referido usando @+id/. Se você refatorar o nome de id original por meio do Android Studio, ele também refatora o layout incluído.

<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
fonte
2

Em um caso de uso, <RecyclerView>encontre o id de <include>usando uma instância de visão inflada ou então ele retornará 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
fonte
1

Se você definiu id para qualquer tag raiz do layout incluído, você pode usar esse id ou pode definir id para o layout incluído.

Mas você não pode definir id para ambos, pode lançar uma exceção.

<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>

Ou

<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
fonte
0

Ao falar sobre inclusão, você tem um id na visualização raiz dentro do arquivo de layout incluído ou na própria linha de inclusão e não em ambos. Por exemplo:

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

Arquivo de layout 1

<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>

O exemplo acima está errado porque tecnicamente você tem dois ids declarados para o mesmo layout. Portanto, o que você precisa fazer é escolher qual elemento terá o id.

Mossman252
fonte
0

Uau, não acredito que essa pergunta ainda não tenha a resposta certa. É uma merda de tags simples. Você só pode mudar as coisas que começam com as android:layout_que android:idnão correspondem. Portanto, a resposta é que você não pode. Desculpe. O que você pode fazer em vez disso é criar uma classe que será um ViewGroup que aumentará as visualizações incluídas dentro, e então adicionar isso como uma tag em seu layout, mas isso é tudo.

TheHebrewHammer
fonte