Cara menentukan id saat menggunakan termasuk dalam file xml layout

117

Dalam file layout xml saya, saya telah menyertakan file layout xml lainnya (masing-masing dengan id android yang berbeda).

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

Tetapi ketika saya menjalankannya di emulator, dan memulai Hierarchy Viewer, setiap tata letak masih menampilkan 'NO_ID', dan dalam kode saya, saya memiliki findViewById(R.id.test1)dan findViewById(R.id.test2)keduanya mengembalikan null.

Adakah yang bisa membantu saya dengan masalah saya?

hap497
sumber
6
ID Anda tidak memiliki @simbol.
AutonomousApps

Jawaban:

288

Tentukan ID di <include>

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

Kemudian gunakan dua findViewByIduntuk mengakses bidang di tata letak

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

Dengan menggunakan pendekatan itu, Anda dapat mengakses bidang apa pun di semua penyertaan yang Anda miliki.

Ron Romero
sumber
18
Metode ini mengembalikan saya nilai nol untuk objek test1View.
Nirav Shah
4
Saya tidak benar-benar melihat perbedaannya, dapatkah Anda jelaskan?
Goddchen
30
Saya menemukan bahwa jika tata letak yang kami sertakan menggunakan merge, ini tidak akan membantu. Namun jika penggabungan tidak digunakan, ini berfungsi.
Zlatko
@Zlatko Ya, dan ini tidak dapat berfungsi mergebahkan dalam teori, karena hasil dari menyertakan mergebukan tampilan tunggal, tetapi sekumpulan dari mereka. Jadi tidak apa-apa.
Nama Tampilan
1
Ini hanya akan berfungsi jika penggabungan tidak digunakan. Jika terjadi penggabungan, tidak mungkin seperti yang ditentukan di sini: code.google.com/p/android/issues/detail?id=36918#c3
Zahid Rasheed
61

Saya menemukan, bahwa jika Anda menggunakan <merge> tag dalam tata letak include Anda, maka ID dari include ditransfer ke tag gabungan yang bukan tampilan nyata.

Jadi, hapus gabungan, atau ganti dengan beberapa tata letak.

Tor Norbye menulis :

The <include>tag tidak tampilan yang nyata, sehingga findByView tidak akan menemukannya. Atribut @id (dan atribut lain yang Anda setel pada tag include) akan diterapkan pada tag root dari tata letak yang disertakan. Jadi activity.getView (R.id.included1) Anda seharusnya menjadi <TextView>dirinya sendiri.

loki19
sumber
3
Bagus. Saya menghapus tag gabungan dan mulai berfungsi tetapi pertanyaan saya di sini adalah apa penggunaan tag gabungan jika ada tata letak yang disertakan berfungsi tanpanya?
Ankur Chaudhary
35

Romain Guy menunjukkan bahwa Anda dapat mengganti ID dari tata letak yang disertakan dengan meletakkan android:idatribut di dalam <include>tag.

<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
Daniel Yankowsky
sumber
1
Ini benar. Cara untuk mereferensikan elemen root dalam file layout yang disertakan adalah dengan id yang diberikan dalam tag 'include' (kecuali jika tidak diberikan).
Tom R
1
ID dalam <include> = root's ID dalam layout yang disertakan
Fadils
Tampak bagi saya jika saya menyetel id terlebih dahulu (di tag include, itu menimpa id dari tata letak yang disertakan, kan?), Saya akan memiliki tag include yang awalnya '@ + id / cell1' dan kemudian layout = ' @ layout / workspace_screen 'akan menimpa android: id lagi dengan id dari layout yang disertakan. Jawaban @Ron Romero lebih masuk akal bagi saya.
Neon Warge
14

Menurut saya, jawaban teratas melewatkan poin terpenting dan mungkin menyesatkan orang agar mengira <include/>tag menciptakan Tampilan yang menyimpan konten penyertaan.

Titik kunci adalah yang mencakup ini id yang dilewatkan ke akar pandangan termasuk tata letak file ini.

Artinya ini:

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

Menjadi ini:

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

yes adalah seperti ini, tetapi hati-hati ketika tata letak yang disisipkan dalam bidang include adalah tata letak khusus dan Anda ingin mengakses tata letak root tersebut. Layout itu dalam kasus ini @ layout / test test, sebenarnya dikembalikan di baris pertama.

test test1View = (test)findViewById(R.id.test1);
lelucon
sumber
2
  1. Anda harus menyetel id setiap menyertakan tag
  2. termasuk elemen anak mengatur id baru. jika Anda melihat cara menghasilkan id baru, lihat entri ini: https://stackoverflow.com/a/15442898/1136117
Sinan Ergin
sumber
2

Masalahnya adalah kami mencoba menggunakan id yang tidak dideklarasikan dalam file layout saat ini. Alih-alih mendeklarasikan lagi, id dapat dengan mudah dirujuk menggunakan @+id/. Jika Anda memfaktorkan ulang nama id asli melalui Android Studio, ia juga akan memfaktor ulang dalam tata letak yang disertakan.

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

Dalam kasus menggunakan <RecyclerView>find id dari <include>dengan menggunakan sebuah instance dari view yang digelembungkan atau akan mengembalikan null .

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

Jika Anda telah menyetel id ke salah satu tag root dari tata letak yang disertakan, Anda dapat menggunakan id itu atau Anda dapat menyetel id ke tata letak yang disertakan.

Tapi Anda tidak bisa menyetel id ke keduanya, itu mungkin melempar pengecualian.

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

Atau

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

Saat berbicara tentang include, Anda memiliki id pada tampilan root di dalam file layout yang disertakan atau pada baris include itu sendiri dan bukan pada keduanya. Sebagai contoh:

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

Tata letak 1 file

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

Contoh di atas salah karena secara teknis Anda memiliki dua id yang dideklarasikan untuk layout yang sama. Jadi yang harus Anda lakukan adalah memilih elemen mana yang akan memiliki id.

mossman 252
sumber
0

Wow, saya tidak percaya pertanyaan ini belum memiliki jawaban yang benar. Tag sederhana itu payah. Anda hanya dapat mengubah hal-hal yang dimulai dengan android:layout_yang android:idtidak cocok. Jadi jawabannya tidak bisa. Maaf. Yang dapat Anda lakukan adalah membuat kelas yang akan menjadi ViewGroup yang akan memekarkan tampilan yang disertakan di dalamnya, lalu menambahkannya sebagai tag dalam tata letak Anda, tapi itu saja.

TheHebrewHammer
sumber