Dari yang saya baca Anda dapat menetapkan onClick
penangan ke tombol dalam dua cara.
Menggunakan android:onClick
atribut XML tempat Anda hanya menggunakan nama metode publik dengan tanda tangan void name(View v)
atau dengan menggunakan setOnClickListener
metode tempat Anda melewatkan objek yang mengimplementasikan OnClickListener
antarmuka. Yang terakhir sering membutuhkan kelas anonim yang secara pribadi saya tidak suka (selera pribadi) atau mendefinisikan kelas internal yang mengimplementasikan OnClickListener
.
Dengan menggunakan atribut XML Anda hanya perlu mendefinisikan metode, bukan kelas jadi saya bertanya-tanya apakah hal yang sama dapat dilakukan melalui kode dan tidak dalam tata letak XML.
onClick
atributnya di file tata letak. Ini dilakukan berkat parameterView v
. Anda cukup memeriksaif (v == findViewById(R.id.button1
)) dll.v.getId() == R.id.button1
, karena Anda tidak harus menemukan kontrol yang sebenarnya dan melakukan perbandingan. Dan Anda dapat menggunakan banyakswitch
bukannya seandainya.Jawaban:
Tidak, itu tidak mungkin melalui kode. Android hanya mengimplementasikan
OnClickListener
untuk Anda ketika Anda mendefinisikanandroid:onClick="someMethod"
atribut.Kedua cuplikan kode itu sama, hanya diterapkan dengan dua cara berbeda.
Implementasi Kode
Di atas adalah implementasi kode dari sebuah
OnClickListener
. Dan ini adalah implementasi XML.Implementasi XML
Di latar belakang, Android tidak melakukan apa pun selain kode Java, memanggil metode Anda pada acara klik.
Perhatikan bahwa dengan XML di atas, Android akan mencari
onClick
metodemyFancyMethod()
hanya di Aktivitas saat ini. Ini penting untuk diingat jika Anda menggunakan fragmen, karena meskipun Anda menambahkan XML di atas menggunakan fragmen, Android tidak akan mencarionClick
metode dalam.java
file fragmen yang digunakan untuk menambahkan XML.Hal penting lain yang saya perhatikan. Anda mengatakan Anda tidak suka metode anonim . Anda bermaksud mengatakan Anda tidak suka kelas anonim .
sumber
myFancyMethod()
) di Activity saat ini. Ini penting jika Anda menggunakan fragmen, karena cara terprogram mengatur pendengar onclick mungkin akan memiliki metode yang menangani klik di onCreateView () ... fragmen yang tidak akan ditemukan jika dirujuk dari XML.Ketika saya melihat jawaban teratas, itu membuat saya menyadari bahwa masalah saya tidak menempatkan parameter (Lihat v) pada metode mewah:
Ketika mencoba mengaksesnya dari xml, orang harus menggunakannya
Semoga itu bisa membantu seseorang.
sumber
android:onClick
untuk API level 4 dan seterusnya, jadi jika Anda menargetkan <1,6, maka Anda tidak dapat menggunakannya.sumber
Periksa apakah Anda lupa mempublikasikan metode ini!
sumber
Menentukan
android:onClick
hasil atributButton
misalnya memanggil secarasetOnClickListener
internal. Karenanya sama sekali tidak ada perbedaan.Untuk memiliki pemahaman yang jelas, mari kita lihat bagaimana
onClick
atribut XML ditangani oleh framework.Ketika file tata letak meningkat, semua tampilan yang ditentukan di dalamnya adalah instantiated. Dalam kasus khusus ini,
Button
instance dibuat menggunakanpublic Button (Context context, AttributeSet attrs, int defStyle)
konstruktor. Semua atribut dalam tag XML dibaca dari bundel sumber daya dan diteruskanAttributeSet
ke konstruktor.Button
kelas diwarisi dariView
kelas yang menghasilkanView
konstruktor dipanggil, yang mengatur pengaturan panggilan balik melalui peneleponsetOnClickListener
.Atribut onClick didefinisikan dalam attrs.xml , disebut dalam View.java sebagai
R.styleable.View_onClick
.Berikut adalah kode
View.java
yang berfungsi untuk Anda dengan meneleponsetOnClickListener
sendiri.Seperti yang Anda lihat,
setOnClickListener
dipanggil untuk mendaftarkan panggilan balik, seperti yang kita lakukan dalam kode kita. Hanya perbedaan yang digunakannyaJava Reflection
untuk memanggil metode panggilan balik yang ditentukan dalam Aktivitas kami.Berikut adalah alasan untuk masalah yang disebutkan dalam jawaban lain:
Java Class getMethod
digunakan, hanya fungsi dengan penentu akses publik yang dicari. Kalau tidak siap untuk menanganiIllegalAccessException
pengecualian.getContext().getClass().getMethod()
call membatasi pencarian metode ke konteks saat ini, yaitu Activity dalam kasus Fragment. Oleh karena itu metode dicari dalam kelas Activity dan bukan kelas Fragment.Java Class getMethod
mencari metode yang menerimaView.class
parameter.sumber
Ada jawaban yang sangat baik di sini, tetapi saya ingin menambahkan satu baris:
Di
android:onclick
dalam XML, Android menggunakan refleksi java di belakang layar untuk menangani ini.Dan seperti yang dijelaskan di sini, refleksi selalu memperlambat kinerja. (terutama pada Dalvik VM). Mendaftar
onClickListener
adalah cara yang lebih baik.sumber
Perhatikan bahwa jika Anda ingin menggunakan fitur XML onClick, metode yang sesuai harus memiliki satu parameter, yang tipenya harus cocok dengan objek XML.
Misalnya, sebuah tombol akan ditautkan ke metode Anda melalui string namanya:
android:onClick="MyFancyMethod"
tetapi deklarasi metode harus menunjukkan:...MyFancyMethod(View v) {...
Jika Anda mencoba untuk menambahkan fitur ini ke item menu , itu akan memiliki sintaks yang sama persis dalam file XML tetapi metode Anda akan dinyatakan sebagai:
...MyFancyMethod(MenuItem mi) {...
sumber
Cara lain untuk mengatur pendengar klik Anda adalah dengan menggunakan XML. Cukup tambahkan atribut android: onClick ke tag Anda.
Merupakan praktik yang baik untuk menggunakan atribut xml "onClick" di atas kelas Java anonim jika memungkinkan.
Pertama-tama, mari kita lihat perbedaan dalam kode:
Atribut XML / AtClick atribut
Bagian XML
Porsi Jawa
Kelas Java anonim / setOnClickListener
Bagian XML
Porsi Jawa
Berikut adalah manfaat menggunakan atribut XML di atas kelas Java anonim:
Tentu saja, tidak selalu mungkin untuk menggunakan atribut Xml, berikut adalah alasan mengapa kami tidak memilihnya:
sumber
Dengan Java 8, Anda mungkin bisa menggunakan Referensi Metode untuk mencapai apa yang Anda inginkan.
Asumsikan ini adalah
onClick
pengendali acara Anda untuk sebuah tombol.Kemudian, Anda memberikan
onMyButtonClicked
referensi metode instance dalamsetOnClickListener()
panggilan seperti ini.Ini akan memungkinkan Anda untuk menghindari secara eksplisit mendefinisikan kelas anonim sendiri. Namun saya harus menekankan bahwa Referensi Metode Java 8 sebenarnya hanya gula sintaksis. Ini sebenarnya membuat turunan kelas anonim untuk Anda (seperti halnya ekspresi lambda) maka kehati-hatian yang sama seperti pengendali event gaya lambda diaplikasikan saat Anda datang ke pencabutan handler acara Anda. Artikel ini menjelaskannya dengan sangat bagus.
PS. Bagi mereka yang ingin tahu bagaimana saya benar-benar dapat menggunakan fitur bahasa Java 8 di Android, itu adalah milik perpustakaan retrolambda .
sumber
Ya, Anda dapat membuat
fragment
atauactivity
menerapkanView.OnClickListener
dan ketika Anda menginisialisasi objek tampilan baru Anda dalam kode, Anda cukup melakukannya
mView.setOnClickListener(this);
dan ini secara otomatis mengatur semua objek tampilan dalam kode untuk menggunakan
onClick(View v)
metode yang Andafragment
atauactivity
dll miliki.untuk membedakan tampilan yang disebut
onClick
metode, Anda dapat menggunakan pernyataan sakelar padav.getId()
metode.Jawaban ini berbeda dari yang mengatakan "Tidak, itu tidak mungkin melalui kode"
sumber
sumber
Mendukung jawaban Ruivo, ya Anda harus mendeklarasikan metode sebagai "publik" untuk dapat digunakan di Android XML onclick - Saya sedang mengembangkan penargetan aplikasi dari API Level 8 (minSdk ...) hingga 16 (targetSdk ...).
Saya menyatakan metode saya sebagai pribadi dan menyebabkan kesalahan, hanya menyatakannya sebagai pekerjaan umum yang hebat.
sumber
Hati-hati, meskipun
android:onClick
XML tampaknya merupakan cara yang nyaman untuk menangani klik,setOnClickListener
implementasinya melakukan sesuatu yang lebih daripada menambahkanonClickListener
. Memang, ini membuat properti viewclickable
menjadi true.Meskipun mungkin tidak menjadi masalah pada sebagian besar implementasi Android, menurut konstruktor telepon, tombol selalu default untuk diklik = benar tetapi konstruktor lain pada beberapa model ponsel mungkin memiliki default yang dapat diklik = salah pada tampilan non Tombol.
Jadi pengaturan XML tidak cukup, Anda harus berpikir setiap saat untuk menambahkan
android:clickable="true"
pada tombol non, dan jika Anda memiliki perangkat di mana defaultnya dapat diklik = benar dan Anda lupa sekali untuk meletakkan atribut XML ini, Anda tidak akan melihat masalah saat runtime tetapi akan mendapatkan umpan balik di pasar saat itu akan berada di tangan pelanggan Anda!Selain itu, kita tidak pernah bisa yakin tentang bagaimana proguard akan mengaburkan dan mengganti nama atribut XML dan metode kelas, jadi tidak 100% aman bahwa mereka tidak akan pernah memiliki bug suatu hari.
Jadi jika Anda tidak pernah ingin mengalami masalah dan tidak pernah memikirkannya, lebih baik menggunakan
setOnClickListener
atau perpustakaan seperti ButterKnife dengan anotasi@OnClick(R.id.button)
sumber
onClick
atribut XML juga menetapkanclickable = true
karena panggilansetOnClickListener
diView
internalMisalkan, Anda ingin menambahkan event klik seperti ini
main.xml
Dalam file java, Anda harus menulis metode seperti metode ini.
sumber
Saya Tulis kode ini dalam file xml ...
Dan tulis kode ini dalam fragmen ...
sumber
Cara terbaik untuk melakukan ini adalah dengan kode berikut:
sumber
Untuk membuat hidup Anda lebih mudah dan menghindari Kelas Anonim di setOnClicklistener (), terapkan Antarmuka View.OnClicklistener seperti di bawah ini:
kelas publik YourClass memperluas CommonActivity mengimplementasikan View.OnClickListener, ...
ini menghindari:
dan langsung menuju:
sumber