Pertama-tama: ya, saya membaca semua utas lainnya tentang topik ini. Dan bukan hanya mereka yang berasal dari situs ini ... (Anda lihat, saya sedikit frustrasi)
Sebagian besar dari mereka datang dengan saran untuk digunakan, android:id
bukan hanya id
dalam file XML. Aku melakukannya.
Dari yang lain, saya belajar, itu View.findViewById
bekerja berbeda dari Activity.findViewById
. Saya menanganinya juga.
Di saya location_layout.xml
, saya menggunakan:
<FrameLayout .... >
<some.package.MyCustomView ... />
<LinearLayout ... >
<TextView ...
android:id="@+id/txtLat" />
...
</LinearLayout>
</FrameLayout>
Dalam Aktivitas saya, saya lakukan:
...
setContentView( R.layout.location_layout );
dan di kelas tampilan khusus saya:
...
TextView tv = (TextView) findViewById( R.id.txtLat );
yang kembali null
. Melakukan ini, Aktivitas saya berfungsi dengan baik. Jadi mungkin itu karena Activity.findViewById
dan View.findViewById
perbedaan. Jadi saya menyimpan konteks yang diteruskan ke konstruktor tampilan pabean secara lokal dan mencoba:
...
TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat );
yang juga dikembalikan null
.
Kemudian, saya mengubah tampilan kustom saya untuk memperpanjang ViewGroup
bukan View
dan mengubah location_layout.xml
untuk membiarkan TextView
menjadi anak langsung dari tampilan kustom saya, sehingga View.findViewById
harus bekerja sebagai seharusnya. Mengejutkan: itu tidak menyelesaikan apa pun.
Jadi apa yang saya lakukan salah?
Saya akan menghargai komentar Anda.
sumber
Jawaban:
Mungkin karena Anda memanggilnya terlalu dini. Tunggu sampai
onFinishInflate()
. Berikut adalah contoh proyek yang menunjukkan suatu kebiasaanView
mengakses kontennya.sumber
onFinishInflate()
.Mungkin, Anda menelepon
findViewById
sebelum meneleponsetContentView
? Jika demikian, coba panggilfindViewById
SETELAH panggilansetContentView
sumber
Pastikan Anda tidak memiliki beberapa versi tata letak untuk kepadatan layar yang berbeda. Saya mengalami masalah ini sekali ketika menambahkan id baru ke tata letak yang ada tetapi lupa untuk memperbarui versi hdpi. Jika Anda lupa memperbarui semua versi file tata letak itu akan berfungsi untuk beberapa kepadatan layar tetapi tidak yang lain.
sumber
FindViewById bisa menjadi nol jika Anda memanggil konstruktor super yang salah dalam tampilan kustom. Tag ID adalah bagian dari attrs, jadi jika Anda mengabaikan attrs, Anda menghapus ID.
Ini salah
Ini benar
sumber
Dalam kasus saya, saya punya 2 kegiatan di proyek saya,
main.xml
danmain2.xml
. Dari awal,main2
adalah salinanmain
, dan semuanya bekerja dengan baik, sampai aku tambah baruTextView
untukmain2
, sehinggaR.id.textview1
menjadi tersedia untuk sisa aplikasi. Kemudian saya mencoba mengambilnya dengan panggilan standar:dan itu selalu nol. Ternyata, bahwa dalam
onCreate
konstruktor saya instantiating bukanmain2
, tetapi yang lain. Saya punya:dari pada
Saya perhatikan ini setelah saya tiba di sini, di situs.
sumber
Di samping penyebab klasik, disebutkan di tempat lain:
setContentView()
sebelumnyafindViewById()
id
Anda inginkan ada di tampilan atau tata letak yang Anda berikansetContentView()
id
tidak secara tidak sengaja diduplikasi dalam tata letak yang berbedaAda satu yang saya temukan untuk tampilan khusus dalam tata letak standar, yang bertentangan dengan dokumentasi:
Secara teori Anda dapat membuat tampilan khusus dan menambahkannya ke tata letak ( lihat di sini ). Namun, saya telah menemukan bahwa dalam situasi seperti itu, terkadang
id
atribut berfungsi untuk semua tampilan di tata letak kecuali yang kustom. Solusi yang saya gunakan adalah:FrameLayout
properti tata letak yang sama seperti yang Anda inginkan untuk tampilan kustom. Berikan yang sesuaiid
, katakanlahframe_for_custom_view
.Dalam
onCreate
:yang menempatkan tampilan khusus dalam bingkai.
sumber
sumber
Sebuah jawaban untuk mereka yang menggunakan ExpandableListView dan mengalami pertanyaan ini berdasarkan judulnya.
Saya mengalami kesalahan ini ketika mencoba untuk bekerja dengan TextViews di tampilan anak dan grup saya sebagai bagian dari implementasi ExpandableListView.
Anda dapat menggunakan sesuatu seperti yang berikut ini dalam implementasi Anda dari metode getChildView () dan getGroupView ().
Saya menemukan ini di sini .
sumber
Saya cukup baru di Android / Eclipse, karena kesalahan saya menambahkan hal-hal UI untuk
activity_main.xml
bukanfragment_main.xml
. Butuh waktu beberapa jam untuk mencari tahu ...sumber
FWIW, saya tidak melihat ada yang menyelesaikan ini dengan cara yang persis sama seperti yang saya butuhkan. Tidak ada keluhan pada waktu kompilasi, tapi saya mendapatkan tampilan nol saat runtime, dan memanggil berbagai hal dengan urutan yang benar. Yaitu, findViewById () setelah setContentView (). Masalahnya ternyata tampilan saya didefinisikan dalam content_main.xml, tetapi di activity_main.xml saya, saya tidak memiliki pernyataan yang satu ini:
Ketika saya menambahkan itu ke activity_main.xml, tidak ada lagi NullPointer.
sumber
Saya punya masalah yang sama. Saya menggunakan pustaka pihak ketiga yang memungkinkan Anda mengganti adaptor mereka untuk GridView dan menentukan tata letak Anda sendiri untuk setiap sel GridView.
Saya akhirnya menyadari apa yang terjadi. Eclipse masih menggunakan file xml tata letak perpustakaan untuk setiap sel di GridView, meskipun itu tidak menunjukkan hal ini. Dalam adaptor khusus saya, itu menunjukkan bahwa ia menggunakan sumber daya xml dari proyek saya sendiri meskipun saat runtime, itu tidak.
Jadi yang saya lakukan adalah memastikan layout dan id xml kustom saya berbeda dari yang masih ada di perpustakaan, membersihkan proyek dan kemudian mulai membaca tata letak kustom yang benar yang ada di proyek saya.
Singkatnya, berhati-hatilah jika Anda mengganti adaptor perpustakaan pihak ketiga dan menentukan tata letak Anda sendiri xml agar adaptor dapat digunakan. Jika tata letak Anda di dalam proyek Anda memiliki nama file yang sama dengan yang ada di perpustakaan, Anda mungkin menemukan bug yang sangat sulit ditemukan!
sumber
Dalam kasus khusus saya, saya mencoba menambahkan footer ke ListView. Panggilan berikut di onCreate () kembali nol.
Mengubah ini untuk mengembang tampilan footer alih-alih menemukannya dengan ID menyelesaikan masalah ini.
sumber
Dalam kasus saya, saya menggunakan ExpandableListView dan telah saya atur
android:transcriptMode="normal"
. Ini menyebabkan beberapa anak dalam grup yang dapat diperluas menghilang dan saya biasa mendapatkan pengecualian NULL ketika saya pernah menggunakan daftar gulir.sumber
Bagi saya, saya memiliki dua tata letak xml untuk aktivitas yang sama - satu dalam mode potret dan satu di lanskap. Tentu saja saya telah mengubah id dari suatu objek di landscape xml tetapi lupa untuk membuat perubahan yang sama dalam versi potret. Pastikan jika Anda mengubah yang Anda lakukan sama dengan xml lain atau Anda tidak akan mendapatkan kesalahan sampai Anda menjalankan / debug itu dan tidak dapat menemukan id Anda tidak berubah. Oh, kesalahan bodoh, mengapa Anda harus menghukum saya begitu?
sumber
Setel konten aktivitas dari sumber daya tata letak. yaitu.,
setContentView(R.layout.basicXml)
;sumber
Selain solusi di atas, Anda memastikan bahwa
tools:context=".TakeMultipleImages"
dalam tata letak nilai yang sama di file mainfest.xml:android:name=".TakeMultipleImages"
untuk elemen aktivitas yang sama. itu terjadi ketika menggunakan salin dan tempel untuk membuat aktivitas barusumber
Saya memiliki masalah yang sama, tetapi saya pikir ini layak untuk dibagikan kepada kalian. Jika Anda harus menemukanViewById di tata letak khusus, misalnya:
Anda tidak dapat memperoleh tampilan dalam konstruktor. Anda harus memanggil findViewById setelah tampilan meningkat. Mereka adalah metode yang dapat Anda ganti
onFinishInflate
sumber
Hanya ingin melempar kasus khusus saya di sini. Mungkin bisa membantu seseorang di telepon.
Saya menggunakan arahan dalam Android UI XML saya seperti ini:
Tampilan induk:
Tampilan anak (retry_button):
.findViewById (R.id.retry) akan selalu mengembalikan nol. Tapi, jika saya memindahkan ID dari tampilan anak ke tag sertakan, itu mulai berfungsi.
Induk tetap:
Anak tetap:
sumber
Kasus saya tidak seperti di atas, tidak ada solusi yang berhasil. Saya menganggap pandangan saya terlalu jauh ke dalam hierarki tata letak. Saya memindahkannya satu tingkat ke atas dan bukan nol lagi.
sumber
Dalam kasus saya, saya telah meningkatkan tata letak tetapi pandangan anak kembali nol. Awalnya saya punya ini:
Namun, ketika saya mengubahnya ke yang berikut ini berfungsi:
Kuncinya adalah secara khusus referensi tata letak yang sudah meningkat untuk mendapatkan tampilan anak. Artinya, untuk menambahkan
footerView
:sumber
Dalam pengalaman saya, sepertinya ini juga bisa terjadi ketika kode Anda dipanggil setelah OnDestroyView (ketika fragmen berada di tumpukan belakang). Jika Anda memperbarui UI pada input dari BroadCastReceiver, Anda harus memeriksa apakah ini masalahnya .
sumber
INFLATE LAYOUT !! (yang berisi id)
Dalam kasus saya findViewById () mengembalikan nol, karena tata letak di mana elemen ditulis, tidak meningkat ...
Misalnya. fragment_layout.xml
findViewById (R.id.listview) mengembalikan nol, karena saya belum melakukan inflater.inflate (R.layout.fragment_layout, ..., ...); sebelum itu.
Semoga jawaban ini membantu Anda semua.
sumber
Perbaikan saya adalah hanya membersihkan proyek.
sumber
findViewById juga dapat mengembalikan nol jika Anda berada di dalam Fragmen. Seperti dijelaskan di sini: findViewById di Fragment
Anda harus memanggil getView () untuk mengembalikan Tampilan tingkat atas di dalam Fragmen. Kemudian Anda dapat menemukan item tata letak (tombol, tampilan teks, dll)
sumber
Saya sudah mencoba semua hal di atas tidak berfungsi .. jadi saya harus membuat ImageView saya statis
public static ImageView texture;
dan kemudiantexture = (ImageView) findViewById(R.id.texture_back);
, saya tidak berpikir itu pendekatan yang baik, tetapi ini benar-benar bekerja untuk kasus saya :)sumber
Dalam kasus saya, findViewById mengembalikan nol ketika saya memindahkan panggilan dari objek induk ke objek adaptor yang dipakai oleh induk. Setelah mencoba trik yang tercantum di sini tanpa hasil, saya memindahkan findViewById kembali ke objek induk dan meneruskan hasilnya sebagai parameter selama instantiation objek adaptor. Misalnya, saya melakukan ini di objek induk:
Lalu saya melewati hdSpinner sebagai parameter selama pembuatan objek adaptor:
sumber
Itu macet untuk saya karena salah satu bidang di id aktivitas saya cocok dengan id di aktivitas lain. Saya memperbaikinya dengan memberikan id unik.
Dalam id bidang kata sandi loginActivity.xml saya adalah "kata sandi". Dalam aktivitas registrasi saya, saya hanya memperbaikinya dengan memberikan id r_password, lalu mengembalikannya bukan objek nol:
sumber
Saya menghadapi masalah yang sama ketika saya mencoba melakukan tampilan kustom untuk
ListView
.Saya menyelesaikannya hanya dengan melakukan ini:
sumber
Cara melakukan debug dan menemukan masalah:
Dalam kasus saya, saya menggunakan activity_main.xml di modul aplikasi saya dan juga modul perpustakaan saya. Jadi ketika saya melakukan langkah-langkah di atas, alih-alih tata letak yang saya rancang di perpustakaan, tata letak di dalam modul aplikasi meningkat.
Jadi saya mengubah nama file activity_main.xml menjadi activity_main_lib.xml.
Jadi pastikan Anda tidak memiliki nama tata letak duplikat di seluruh proyek Anda .
sumber