Bagian berikut menjelaskan beberapa konsep utama untuk proses tarik lalu lepas.
Proses tarik lalu lepas
Ada empat langkah atau status dalam proses tarik lalu lepas: dimulai, melanjutkan, dilepas, dan berakhir.
- Dimulai
Sebagai respons terhadap gestur tarik pengguna, aplikasi Anda akan memanggil
startDragAndDrop()
untuk memberi tahu sistem agar memulai operasi tarik lalu lepas. Argumen metode memberikan hal berikut:- Data yang akan ditarik.
- Callback untuk menggambar bayangan tarik
- Metadata yang menjelaskan data yang ditarik
- Sistem akan merespons dengan melakukan callback ke aplikasi Anda untuk mendapatkan bayangan tarik. Sistem kemudian menampilkan bayangan tarik di perangkat.
- Selanjutnya, sistem mengirimkan peristiwa tarik dengan jenis tindakan
ACTION_DRAG_STARTED
ke pemroses peristiwa tarik untuk semua objekView
dalam tata letak saat ini. Untuk terus menerima peristiwa tarik, termasuk kemungkinan peristiwa lepas, pemroses peristiwa tarik harus menampilkantrue
. Tindakan ini mendaftarkan pemroses ke sistem. Hanya pemroses terdaftar yang akan terus menerima peristiwa tarik. Pada tahap ini, pemroses juga dapat mengubah tampilan objekView
target lepas untuk menunjukkan bahwa tampilan dapat menerima peristiwa lepas. - Jika pemroses peristiwa tarik menampilkan
false
, pemroses tidak akan menerima peristiwa tarik untuk operasi saat ini hingga sistem mengirimkan peristiwa tarik dengan jenis tindakanACTION_DRAG_ENDED
. Dengan menampilkanfalse
, pemroses memberi tahu sistem bahwa ia tidak tertarik dengan operasi tarik lalu lepas dan tidak ingin menerima data yang ditarik.
- Melanjutkan
- Pengguna melanjutkan proses tarik. Saat bayangan tarik memotong
kotak pembatas target lepas, sistem akan mengirimkan satu atau beberapa peristiwa tarik ke
pemroses peristiwa tarik target. Pemroses dapat mengubah tampilan
target lepas
View
sebagai respons terhadap peristiwa tersebut. Misalnya, jika peristiwa itu menunjukkan bahwa bayangan tarik memasuki kotak pembatas target lepas—jenis tindakanACTION_DRAG_ENTERED
—pemroses dapat bereaksi dengan menyorotView
. - Dilepas
- Pengguna melepaskan bayangan tarik di dalam kotak pembatas target
pelepasan. Sistem mengirimkan peristiwa tarik ke pemroses target lepas dengan jenis tindakan
ACTION_DROP
. Objek peristiwa tarik berisi data yang diteruskan ke sistem dalam panggilan kestartDragAndDrop()
yang memulai operasi ini. Pemroses diharapkan menampilkan booleantrue
ke sistem jika pemroses berhasil memproses data yang dilepas. : Langkah ini hanya terjadi jika pengguna melepas bayangan tarik di dalam kotak pembatasView
yang pemrosesnya terdaftar untuk menerima peristiwa tarik (target operasi lepas). Jika pengguna merilis bayangan tarik dalam situasi lain, tidak ada peristiwa tarikACTION_DROP
yang dikirim. - Berakhir
Setelah pengguna melepas bayangan tarik, dan setelah sistem mengirim
peristiwa tarik dengan jenis tindakan
ACTION_DROP
, jika perlu, sistem akan mengirim peristiwa tarik dengan jenis tindakanACTION_DRAG_ENDED
untuk menunjukkan bahwa operasi tarik lalu lepas telah selesai. Hal ini dilakukan di mana pun pengguna merilis bayangan tarik. Peristiwa ini dikirim ke setiap pemroses yang terdaftar untuk menerima peristiwa tarik, meskipun pemroses tersebut juga menerima peristiwaACTION_DROP
.
Masing-masing langkah ini dijelaskan secara lebih mendetail di bagian yang disebut Operasi tarik lalu lepas.
Peristiwa tarik
Sistem mengirimkan peristiwa tarik dalam bentuk objek DragEvent
, yang
berisi jenis tindakan yang menjelaskan apa yang terjadi dalam proses tarik-lepas. Tergantung pada jenis tindakan, objek juga dapat berisi data lain.
Pemroses peristiwa tarik menerima objek DragEvent
. Untuk mendapatkan jenis tindakan,
pemroses memanggil
DragEvent.getAction()
.
Ada enam kemungkinan nilai yang ditentukan oleh konstanta dalam class DragEvent
,
yang dijelaskan dalam tabel 1:
Tabel 1. Jenis tindakan DragEvent
Jenis tindakan | Arti |
---|---|
ACTION_DRAG_STARTED |
Aplikasi memanggil startDragAndDrop() dan mendapatkan
bayangan tarik. Jika pemroses ingin terus menerima peristiwa tarik
untuk operasi ini, pemroses harus menampilkan boolean true ke
sistem.
|
ACTION_DRAG_ENTERED |
Bayangan tarik memasuki kotak pembatas View pemroses peristiwa
tarik. Ini adalah jenis tindakan peristiwa pertama yang
diterima pemroses saat bayangan tarik memasuki kotak pembatas.
|
ACTION_DRAG_LOCATION |
Setelah peristiwa
ACTION_DRAG_ENTERED , bayangan tarik masih
berada dalam kotak pembatas View pemroses
peristiwa tarik.
|
ACTION_DRAG_EXITED |
Setelah ACTION_DRAG_ENTERED dan setidaknya satu
peristiwa ACTION_DRAG_LOCATION , bayangan tarik akan bergerak
di luar kotak pembatas View pemroses
peristiwa tarik.
|
ACTION_DROP |
Bayangan tarik dirilis melalui View pemroses peristiwa
tarik. Jenis tindakan ini dikirim ke pemroses objek
View hanya jika pemroses menampilkan boolean
true sebagai respons terhadap
peristiwa tarik ACTION_DRAG_STARTED . Jenis tindakan ini tidak
dikirim jika pengguna merilis bayangan tarik di atas View
yang pemrosesnya tidak terdaftar, atau jika pengguna merilis bayangan
tarik di atas apa pun yang bukan bagian dari tata letak saat ini.
Pemroses menampilkan boolean |
ACTION_DRAG_ENDED |
Sistem mengakhiri operasi tarik lalu lepas. Jenis tindakan ini
tidak perlu didahului oleh peristiwa ACTION_DROP . Jika
sistem mengirim ACTION_DROP , penerimaan
jenis tindakan ACTION_DRAG_ENDED tidak berarti bahwa
operasi lepas berhasil. Pemroses harus memanggil
getResult() ,
seperti yang ditunjukkan dalam tabel 2, untuk mendapatkan nilai yang
ditampilkan sebagai respons terhadap ACTION_DROP . Jika peristiwa
ACTION_DROP tidak terkirim, getResult() akan menampilkan false .
|
Objek DragEvent
juga berisi data dan metadata yang
disediakan aplikasi Anda ke sistem dalam panggilan ke startDragAndDrop()
. Sebagian data
hanya valid untuk jenis tindakan tertentu seperti yang diringkas dalam tabel 2. Untuk mengetahui informasi selengkapnya tentang peristiwa dan data terkaitnya, lihat bagian yang disebut Operasi tarik lalu lepas.
Tabel 2. Data DragEvent yang valid menurut jenis tindakan
getAction() nilai |
getClipDescription() nilai |
getLocalState() nilai |
getX() nilai |
getY() nilai |
getClipData() nilai |
getResult() nilai |
---|---|---|---|---|---|---|
ACTION_DRAG_STARTED |
&periksa; | &periksa; | ||||
ACTION_DRAG_ENTERED |
&periksa; | &periksa; | ||||
ACTION_DRAG_LOCATION |
&periksa; | &periksa; | &periksa; | &periksa; | ||
ACTION_DRAG_EXITED |
&periksa; | &periksa; | ||||
ACTION_DROP |
&periksa; | &periksa; | &periksa; | &periksa; | &periksa; | |
ACTION_DRAG_ENDED |
&periksa; | &periksa; |
Metode DragEvent
getAction()
,
describeContents()
,
writeToParcel()
,
dan toString()
selalu
menampilkan data yang valid.
Jika sebuah metode tidak berisi data yang valid untuk jenis tindakan tertentu, metode tersebut akan menampilkan
null
atau 0, bergantung pada jenis hasilnya.
Bayangan tarik
Selama operasi tarik lalu lepas, sistem akan menampilkan gambar yang ditarik oleh pengguna. Untuk pemindahan data, gambar ini mewakili data yang sedang ditarik. Untuk operasi lainnya, gambar ini mewakili beberapa aspek operasi tarik.
Gambar ini disebut bayangan tarik. Anda membuatnya dengan metode yang Anda deklarasikan untuk
objek
View.DragShadowBuilder
. Anda meneruskan builder ke sistem saat memulai operasi tarik lalu
lepas menggunakan startDragAndDrop()
. Sebagai bagian dari respons terhadap
startDragAndDrop()
, sistem memanggil metode callback yang Anda tentukan di
View.DragShadowBuilder
untuk mendapatkan bayangan tarik.
Class View.DragShadowBuilder
memiliki dua konstruktor:
View.DragShadowBuilder(View)
Konstruktor ini menerima objek
View
apa pun dari aplikasi Anda. Konstruktor menyimpan objekView
dalam objekView.DragShadowBuilder
, sehingga callback dapat mengaksesnya untuk mengonstruksi bayangan tarik. Tampilan tidak harus berupaView
yang dipilih pengguna untuk memulai operasi tarik.Jika menggunakan konstruktor ini, Anda tidak perlu memperluas
View.DragShadowBuilder
atau mengganti metodenya. Secara default, Anda mendapatkan bayangan tarik yang tampilannya sama denganView
yang Anda teruskan sebagai argumen, yang berpusat di bawah lokasi tempat pengguna menyentuh layar.View.DragShadowBuilder()
Jika Anda menggunakan konstruktor ini, tidak ada objek
View
yang tersedia dalam objekView.DragShadowBuilder
. Kolom ditetapkan kenull
. Anda harus memperluasView.DragShadowBuilder
dan mengganti metodenya, atau Anda akan mendapatkan bayangan tarik yang tidak terlihat. Sistem tidak menampilkan error.
Class View.DragShadowBuilder
memiliki dua metode yang bersama-sama membuat bayangan
tarik:
onProvideShadowMetrics()
Sistem akan memanggil metode ini segera setelah Anda memanggil
startDragAndDrop()
. Gunakan metode ini untuk mengirim dimensi dan titik sentuh bayangan tarik ke sistem. Metode ini memiliki dua parameter:outShadowSize
: objekPoint
. Lebar bayangan tarik masuk dix
, dan tingginya masuk diy
.outShadowTouchPoint
: objekPoint
. Titik sentuh adalah lokasi dalam bayangan tarik yang harus berada di bawah jari pengguna selama operasi tarik. Posisi X-nya masuk dix
dan posisi Y-nya masuk diy
.onDrawShadow()
Segera setelah panggilan ke
onProvideShadowMetrics()
, sistem akan memanggilonDrawShadow()
untuk membuat bayangan tarik. Metode ini memiliki argumen tunggal, objekCanvas
yang dibuat oleh sistem dari parameter yang Anda berikan dionProvideShadowMetrics()
. Metode ini menggambar bayangan tarik padaCanvas
yang disediakan.
Untuk meningkatkan performa, buat ukuran bayangan tarik sekecil mungkin. Untuk satu item, sebaiknya Anda menggunakan ikon. Untuk beberapa pilihan, Anda mungkin ingin menggunakan ikon dalam kelompok, bukan gambar penuh yang menyebar memenuhi layar.
Pemroses peristiwa tarik dan metode callback
View
menerima peristiwa tarik dengan pemroses peristiwa tarik yang mengimplementasikan
View.OnDragListener
atau dengan metode callback onDragEvent()
tampilan. Saat
memanggil metode atau pemroses, sistem akan memberikan
argumen DragEvent
.
Umumnya, saat menggunakan pemroses lebih baik menggunakan metode callback. Saat
mendesain UI, biasanya Anda tidak membuat subclass untuk class View
, tetapi menggunakan
metode callback akan memaksa Anda membuat subclass untuk mengganti metode. Sebagai
perbandingan, Anda dapat mengimplementasikan satu class pemroses lalu menggunakannya dengan beberapa
objek View
yang berbeda. Anda juga dapat mengimplementasikannya sebagai class inline
anonim atau ekspresi lambda. Untuk menetapkan pemroses bagi objek View
, panggil
setOnDragListener()
.
Sebagai alternatif, Anda dapat mengubah implementasi default onDragEvent()
tanpa mengganti metode. Tetapkan
OnReceiveContentListener
pada tampilan; untuk detail selengkapnya, lihat
setOnReceiveContentListener()
.
Metode onDragEvent()
kemudian akan melakukan hal berikut secara default:
- Menampilkan true sebagai respons terhadap panggilan ke
startDragAndDrop()
. Memanggil
performReceiveContent()
jika data tarik lalu lepas dilepaskan pada tampilan. Data diteruskan ke metode sebagai objekContentInfo
. Metode ini memanggilOnReceiveContentListener
.Menampilkan true jika data tarik lalu lepas dilepaskan pada tampilan dan
OnReceiveContentListener
akan menggunakan konten apa pun.
Tentukan OnReceiveContentListener
untuk menangani data khusus
untuk aplikasi Anda. Untuk kompatibilitas mundur hingga API level 24, gunakan
OnReceiveContentListener
versi Jetpack.
Anda dapat menggunakan pemroses peristiwa tarik dan metode callback untuk objek View
, yang
dalam hal ini sistem akan memanggil pemroses terlebih dahulu. Sistem tidak memanggil
metode callback kecuali jika pemroses menampilkan false
.
Gabungan dari metode onDragEvent()
dan View.OnDragListener
serupa dengan gabungan dari
onTouchEvent()
dan View.OnTouchListener
yang digunakan dengan peristiwa sentuh.