Saya ingin memperbaiki tampilan header saya di bagian atas layar seperti pada gambar di bawah ini dan tanpa menggunakan pustaka eksternal.
Dalam kasus saya, saya tidak ingin melakukannya menurut abjad. Saya memiliki dua jenis tampilan yang berbeda (Header dan normal). Saya hanya ingin memperbaiki ke atas, tajuk terakhir.
android
header
android-recyclerview
sticky
Jaume Colom
sumber
sumber
Jawaban:
Di sini saya akan menjelaskan bagaimana melakukannya tanpa perpustakaan eksternal. Ini akan menjadi posting yang sangat panjang, jadi persiapkan diri Anda.
Pertama-tama, izinkan saya mengakui @ tim.paetz yang posnya menginspirasi saya untuk memulai perjalanan menerapkan header tempel saya sendiri menggunakan
ItemDecoration
s. Saya meminjam beberapa bagian kodenya dalam implementasi saya.Seperti yang mungkin pernah Anda alami, jika Anda mencoba melakukannya sendiri, sangat sulit menemukan penjelasan yang baik tentang BAGAIMANA benar-benar melakukannya dengan
ItemDecoration
teknik ini. Maksud saya, apa saja langkah-langkahnya? Apa logika di baliknya? Bagaimana cara membuat tajuk menempel di bagian atas daftar? Tidak mengetahui jawaban atas pertanyaan-pertanyaan ini yang membuat orang lain menggunakan perpustakaan eksternal, sedangkan melakukannya sendiri dengan penggunaanItemDecoration
cukup mudah.Kondisi awal
list
item dengan jenis berbeda (bukan dalam arti "tipe Java", tetapi dalam arti jenis "header / item").list
harus menjadi item header.Di sini saya menyediakan kode penuh untuk saya
RecyclerView.ItemDecoration
disebutHeaderItemDecoration
. Kemudian saya menjelaskan langkah-langkah yang diambil secara rinci.Logika bisnis
Jadi, bagaimana cara membuatnya melekat?
Kamu tidak. Anda tidak dapat membuat
RecyclerView
item pilihan Anda hanya berhenti dan tetap di atas, kecuali Anda adalah ahli tata letak khusus dan Anda tahu 12.000+ baris kode untukRecyclerView
hati. Jadi, seperti yang selalu terjadi dengan desain UI, jika Anda tidak bisa membuat sesuatu, palsukan. Anda hanya menggambar tajuk di atas semua yang menggunakanCanvas
. Anda juga harus tahu item mana yang dapat dilihat pengguna saat ini. Itu terjadi begitu saja, yangItemDecoration
dapat memberi AndaCanvas
dan informasi tentang item yang terlihat. Berikut langkah-langkah dasarnya:Dalam
onDrawOver
metodeRecyclerView.ItemDecoration
mendapatkan item pertama (teratas) yang dapat dilihat oleh pengguna.Tentukan header mana yang mewakilinya.
Gambar header yang sesuai di atas RecyclerView dengan menggunakan
drawHeader()
metode.Saya juga ingin menerapkan perilaku tersebut ketika tajuk baru yang akan datang memenuhi tajuk teratas: seharusnya tajuk yang akan datang dengan lembut mendorong tajuk saat ini keluar dari tampilan dan pada akhirnya menggantikannya.
Teknik yang sama untuk "menggambar di atas segalanya" berlaku di sini.
Tentukan kapan header "macet" teratas bertemu dengan header baru yang akan datang.
Dapatkan titik kontak ini (yaitu bagian bawah header tempel gambar Anda dan bagian atas header yang akan datang).
Jika item dalam daftar melanggar "titik kontak" ini, gambar ulang header tempel Anda sehingga bagian bawahnya berada di atas item yang masuk tanpa izin. Anda mencapai ini dengan
translate()
metodeCanvas
. Akibatnya, titik awal dari header teratas akan keluar dari area yang terlihat, dan akan tampak seperti "didorong keluar oleh header yang akan datang". Jika sudah benar-benar hilang, gambar tajuk baru di atas.Sisanya dijelaskan oleh komentar dan anotasi menyeluruh dalam kode yang saya berikan.
Penggunaannya langsung:
Anda
mAdapter
harus menerapkannyaStickyHeaderInterface
agar berfungsi. Penerapannya bergantung pada data yang Anda miliki.Terakhir, di sini saya memberikan gif dengan header setengah transparan, sehingga Anda dapat memahami idenya dan benar-benar melihat apa yang terjadi di balik terpal.
Berikut ilustrasi konsep "menggambar di atas segalanya". Anda dapat melihat bahwa ada dua item "header 1" - satu yang kami gambar dan tetap di atas dalam posisi macet, dan yang lainnya berasal dari kumpulan data dan bergerak dengan semua item lainnya. Pengguna tidak akan melihat cara kerjanya, karena Anda tidak akan memiliki header setengah transparan.
Dan inilah yang terjadi pada fase "mendorong keluar":
Semoga membantu.
Sunting
Berikut adalah implementasi sebenarnya dari
getHeaderPositionForItem()
metode saya di adaptor RecyclerView:Implementasi yang sedikit berbeda di Kotlin
sumber
private View getHeaderViewForItem(int itemPosition, RecyclerView parent) { int headerPosition = mListener.getHeaderPositionForItem(itemPosition); if(headerPosition != mCurrentHeaderIndex) { mCurrentHeader = mListener.createHeaderView(headerPosition, parent); mCurrentHeaderIndex = headerPosition; } return mCurrentHeader; }
Cara termudah adalah dengan membuat Dekorasi Item untuk RecyclerView Anda.
}
XML untuk header Anda di recycler_section_header.xml:
Dan terakhir untuk menambahkan Dekorasi Item ke RecyclerView Anda:
Dengan Dekorasi Item ini Anda dapat membuat tajuk disematkan / lengket atau tidak hanya dengan boolean saat membuat Dekorasi Item.
Anda dapat menemukan contoh kerja lengkap di github: https://github.com/paetztm/recycler_view_headers
sumber
wrap_content
), Anda juga ingin menjalankanfixLayoutSize
setelah menyetel teks judul.Saya telah membuat variasi sendiri dari solusi Sevastyan di atas
... dan berikut adalah implementasi StickyHeaderInterface (saya melakukannya langsung di adaptor pendaur ulang):
Jadi, dalam hal ini header tidak hanya menggambar di atas kanvas, tetapi tampilan dengan selector atau ripple, clicklistener, dll.
sumber
recyclerView.addItemDecoration(HeaderItemDecoration(recyclerView, adapter))
. Maaf, tidak dapat menemukan contoh implementasi, yang saya gunakan. Saya telah mengedit jawaban - menambahkan beberapa teks ke komentarkepada siapa pun yang mencari solusi untuk masalah berkedip / berkedip saat Anda sudah memilikinya
DividerItemDecoration
. sepertinya saya telah menyelesaikannya seperti ini:ini tampaknya berfungsi tetapi adakah yang bisa memastikan bahwa saya tidak merusak apa pun?
sumber
Anda dapat memeriksa dan mengambil implementasi kelas
StickyHeaderHelper
dalam proyek FlexibleAdapter saya , dan menyesuaikannya dengan kasus penggunaan Anda.Tapi, saya menyarankan untuk menggunakan pustaka karena ini menyederhanakan dan mengatur ulang cara Anda biasanya mengimplementasikan Adapters for RecyclerView: Jangan menemukan kembali roda.
Saya juga akan mengatakan, jangan gunakan Dekorator atau perpustakaan usang, serta jangan gunakan perpustakaan yang hanya melakukan 1 atau 3 hal, Anda harus menggabungkan sendiri implementasi perpustakaan lain.
sumber
Decorator
s?Solusi lain, berdasarkan pendengar gulir. Kondisi awal sama dengan jawaban Sevastyan
Tata letak untuk ViewHolder dan tajuk lengket.
item_header.xml
Tata letak untuk RecyclerView
Kelas untuk HeaderItem.
Itu semua berguna. Penerapan adaptor, ViewHolder, dan hal-hal lain, tidak menarik bagi kami.
Antarmuka untuk tampilan header bind.
sumber
for (int i = position; position >= 0; i--){ //should be i >= 0
Yo,
Beginilah cara Anda melakukannya jika Anda menginginkan hanya satu jenis dudukan tongkat saat mulai keluar dari layar (kami tidak peduli tentang bagian mana pun). Hanya ada satu cara tanpa merusak logika RecyclerView internal dari item daur ulang dan itu adalah dengan meluaskan tampilan tambahan di atas item header recyclerView dan meneruskan data ke dalamnya. Aku akan membiarkan kodenya berbicara.
Dan kemudian Anda cukup melakukan ini di adaptor Anda:
Di mana YOUR_STICKY_VIEW_HOLDER_TYPE adalah viewType dari Anda yang seharusnya menjadi pemegang tempel.
sumber
Bagi mereka yang mungkin peduli. Berdasarkan jawaban Sevastyan, apakah Anda ingin membuatnya horizontal scroll. Cukup ubah semua
getBottom()
menjadigetRight()
dangetTop()
kegetLeft()
sumber
Jawabannya sudah ada di sini. Jika Anda tidak ingin menggunakan pustaka apa pun, Anda dapat mengikuti langkah-langkah berikut:
Penjelasan:
Dalam
onCreateViewHolder
metode kami dapat memeriksaviewType
dan bergantung pada nilai (jenis "khusus" kami) mengembangkan tata letak khusus.Sebagai contoh:
dimana
class ItemElement
danclass TitleElement
bisa terlihat seperti biasaViewHolder
:Jadi gagasan tentang semua itu menarik. Tapi saya tertarik jika efektif, karena kita perlu mengurutkan daftar datanya. Dan saya pikir ini akan menurunkan kecepatan. Jika ada pemikiran tentang itu, tolong tulis saya :)
Dan juga pertanyaan terbuka: adalah bagaimana memegang tata letak "khusus" di atas, saat barang-barang didaur ulang. Mungkin menggabungkan semua itu dengan
CoordinatorLayout
.sumber