Saya mencari yang setara dengan addHeaderView untuk tampilan pendaur ulang. Pada dasarnya saya ingin memiliki gambar dengan 2 tombol yang ditambahkan sebagai header ke listview. Apakah ada cara berbeda untuk menambahkan tampilan header ke tampilan pendaur ulang? Contoh untuk panduan akan sangat membantu
EDIT 2 (menambahkan tata letak fragmen):
Setelah menambahkan pernyataan log, sepertinya getViewType hanya pernah menerima posisi 0. Hal ini menyebabkan onCreateView hanya memuat satu tata letak:
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemCount: 5
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemViewType position: 0
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemViewType position: 0
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> getItemViewType position: 0
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> onCreateViewHolder, viewtype: 0
10-26 16:32:53.766 5449-5449/co.testapp I/logger info﹕ Adapter-> onBindViewHolder, viewType: 0
Transisi fragmen untuk memuat CommentFragment:
@Override
public void onPhotoFeedItemClick(View view, int position) {
if (fragmentManager == null)
fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (view.getId() == R.id.button_comment){
CommentFragment commentFragment = CommentFragment.newInstance("","", position);
fragmentTransaction.add(R.id.main_activity, commentFragment,"comment_fragment_tag");
fragmentTransaction.addToBackStack(Constants.TAG_COMMENTS);
fragmentTransaction.commit();
}
}
OnCreateView Fragmen:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_comment, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.list_recylclerview);
mRecyclerView.setLayoutManager(new LinearLayoutManager(_context));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mAdapter = new CommentAdapter(R.layout.row_list_comments, R.layout.row_header_comments, _context, comments);
mRecyclerView.setAdapter(mAdapter);
return view;
}
Fragmen berisi recycleview:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context="co.testapp.fragments.CommentFragment"
android:background="@color/white">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_recylclerview"
android:layout_width="match_parent"
android:layout_height="200dp" />
</RelativeLayout>
</RelativeLayout>
Tata letak baris komentar:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_margin="10dp"
android:background="@color/white">
<!--Profile Picture-->
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/profile_picture"
android:background="@color/blue_testapp"/>
<!--Name-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="First Name Last Name"
android:textSize="16dp"
android:textColor="@color/blue_testapp"
android:id="@+id/name_of_poster"
android:layout_toRightOf="@id/profile_picture"
/>
<!--Comment-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="-5dp"
android:text="This is a test comment"
android:textSize="14dp"
android:textColor="@color/black"
android:id="@+id/comment"
android:layout_below="@id/name_of_poster"
android:layout_toRightOf="@id/profile_picture"/>
</RelativeLayout>
Header
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="300dp"
android:id="@+id/header_photo"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
Kode Adaptor (terima kasih kepada hister untuk memulai saya):
public class CommentAdapter extends RecyclerView.Adapter<ViewHolder>{
private final int rowCardLayout;
public static Context mContext;
private final int headerLayout;
private final String [] comments;
private static final int HEADER = 0;
private static final int OTHER = 0;
public CommentAdapter(int rowCardLayout, int headerLayout, Context context, String [] comments) {
this.rowCardLayout = rowCardLayout;
this.mContext = context;
this.comments = comments;
this.headerLayout = headerLayout;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
logger.i("onCreateViewHolder, viewtype: " + i); //viewtype always returns 0 so OTHER layout is never inflated
if (i == HEADER) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(headerLayout, viewGroup, false);
return new ViewHolderHeader(v);
}
else if (i == OTHER){
View v = LayoutInflater.from(viewGroup.getContext()).inflate(rowCardLayout, viewGroup, false);
return new ViewHolderComments(v);
}
else
throw new RuntimeException("Could not inflate layout");
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
logger.i("onBindViewHolder, viewType: " + i);
if (viewHolder instanceof ViewHolderComments)
((ViewHolderComments) viewHolder).comment.setText(comments[i].toString());
if (viewHolder instanceof ViewHolderHeader)
((ViewHolderHeader) viewHolder).header.setImageResource(R.drawable.image2);
else {
logger.e("no instance of viewholder found");
}
}
@Override
public int getItemCount() {
int count = comments.length + 1;
logger.i("getItemCount: " + count);
return count;
}
@Override
public int getItemViewType(int position) {
logger.i("getItemViewType position: " + position);
if (position == HEADER)
return HEADER;
else
return OTHER;
}
public static class ViewHolderComments extends RecyclerView.ViewHolder {
public TextView comment;
public ImageView image;
public ViewHolderComments(View itemView) {
super(itemView);
comment = (TextView) itemView.findViewById(R.id.comment);
image = (ImageView) itemView.findViewById(R.id.image);
}
}
public static class ViewHolderHeader extends RecyclerView.ViewHolder {
public final ImageView header;
public ViewHolderHeader(View itemView){
super(itemView);
header = (ImageView) itemView.findViewById(R.id.header_photo);
}
}
}
Dengan menggunakan kode di atas, hanya tata letak tajuk yang ditampilkan karena tipe tampilan selalu 0. Tampak seperti ini . Jika saya memaksakan tata letak lainnya seperti ini :
sumber
Jawaban:
Tidak ada cara yang mudah seperti
listview.addHeaderView()
tetapi Anda dapat mencapainya dengan menambahkan tipe ke adaptor Anda untuk header.Berikut ini sebuah contoh
tautan ke inti -> di sini
sumber
private String getItem(int position) { return data[position + 1]; }
Menyebabkan NPE. Karena posisi kami telah bertambah satu, karena tajuk, kami harus mengurangi 1 untuk mendapatkan item yang benar dari data kami [].private String getItem(int position) { return data[position - 1]; }
setSpanSizeLookup
untukGridLayoutManager
, sehingga header akan mengambil semua kolomMudah dan dapat digunakan kembali
ItemDecoration
Header statis dapat dengan mudah ditambahkan dengan
ItemDecoration
dan tanpa perubahan lebih lanjut.Dekorasi juga dapat digunakan kembali karena tidak perlu memodifikasi adaptor atau
RecyclerView
sama sekali.Kode sampel yang disediakan di bawah ini akan memerlukan tampilan untuk ditambahkan ke atas yang hanya dapat meningkat seperti yang lainnya. Ini bisa terlihat seperti ini:
Mengapa statis ?
Jika Anda hanya perlu menampilkan teks dan gambar, solusi ini cocok untuk Anda — tidak ada kemungkinan interaksi pengguna seperti tombol atau pager tampilan, karena itu hanya akan ditarik ke atas daftar Anda.
Penanganan daftar kosong
Jika tidak ada tampilan untuk didekorasi, dekorasi tidak akan ditarik. Anda masih harus menangani daftar kosong sendiri. (Satu solusi yang mungkin dilakukan adalah menambahkan item dummy ke adaptor.)
Kode
Anda dapat menemukan kode sumber lengkap di GitHub termasuk
Builder
untuk membantu inisialisasi dekorator, atau cukup gunakan kode di bawah ini dan berikan nilai Anda sendiri kepada konstruktor.Harap pastikan untuk mengatur yang benar
layout_height
untuk tampilan Anda. mis.match_parent
mungkin tidak berfungsi dengan baik.Harap dicatat: Proyek GitHub adalah taman bermain pribadi saya. Hal ini tidak thorougly diuji, yang mengapa ada perpustakaan belum .
Apa fungsinya?
An
ItemDecoration
adalah gambar tambahan untuk item daftar. Dalam hal ini, dekorasi digambar di bagian atas item pertama.Tampilan diukur dan ditata, lalu ditarik ke bagian atas item pertama. Jika efek paralaks ditambahkan, itu juga akan terpotong ke batas yang benar.
sumber
Jangan ragu untuk menggunakan perpustakaan saya, tersedia di sini .
Ini memungkinkan Anda membuat tajuk
View
untuk apa punRecyclerView
yang menggunakanLinearLayoutManager
atauGridLayoutManager
hanya dengan pemanggilan metode sederhana.sumber
Akan menunjukkan kepada Anda untuk membuat tajuk dengan item dalam tampilan Pendaur Ulang.
Langkah 1- Tambahkan ketergantungan ke file gradle Anda.
Cardview digunakan untuk tujuan dekorasi.
Langkah2 - Buat tiga file xml. Satu untuk aktivitas utama. Kedua untuk tata letak Header. Ketiga untuk tata letak item daftar.
activity_main.xml
header.xml
list.xml
Langkah 3- Buat tiga kelas kacang.
Header.java
ContentItem.java
ListItem.java
Langkah 4- Buat adaptor bernama MyRecyclerAdapter.java
Langkah 5- Di MainActivity tambahkan kode berikut:
Fungsi getList () secara dinamis menghasilkan data untuk header dan untuk item daftar.
sumber
Anda dapat mencapainya menggunakan perpustakaan SectionedRecyclerViewAdapter , ia memiliki konsep "Bagian", di mana Bagian memiliki Header, Footer dan Konten (daftar item). Dalam kasus Anda, Anda mungkin hanya membutuhkan satu Bagian tetapi Anda dapat memiliki banyak Bagian:
1) Buat kelas Bagian kustom:
2) Buat ViewHolder kustom untuk item:
3) Siapkan ReclyclerView Anda dengan SectionedRecyclerViewAdapter
sumber
Anda bisa menempatkan tajuk dan RecyclerView Anda di NestedScrollView:
Agar pengguliran berfungsi dengan benar, Anda harus menonaktifkan pengguliran bersarang di RecyclerView Anda:
sumber
API asli tidak memiliki fitur "addHeader", tetapi memiliki konsep "addItem".
Saya dapat memasukkan fitur spesifik header ini dan meluas untuk footer juga dalam proyek FlexibleAdapter saya . Saya menyebutnya Header dan Footer yang Dapat Digulir .
Di sini cara kerjanya:
Header dan Foot yang Dapat Digulir adalah item-item khusus yang digulirkan bersama dengan semua yang lain, tetapi itu bukan milik item utama (item bisnis) dan mereka selalu ditangani oleh adaptor di samping item utama. Barang-barang itu secara terus-menerus terletak di posisi pertama dan terakhir.
Ada banyak yang bisa dikatakan tentang mereka, lebih baik membaca halaman wiki terperinci .
Selain itu, FlexibleAdapter memungkinkan Anda membuat header / bagian, juga Anda dapat membuatnya lengket dan puluhan fitur lainnya seperti item yang dapat diperluas, gulir tanpa akhir, ekstensi UI dll ... semua dalam satu perpustakaan!
sumber
Berdasarkan posting ini , saya membuat subclass dari RecyclerView.Adapter yang mendukung sejumlah header dan footer yang berubah-ubah.
https://gist.github.com/mheras/0908873267def75dc746
Meskipun tampaknya menjadi solusi, saya juga berpikir hal ini harus dikelola oleh LayoutManager. Sayangnya, saya membutuhkannya sekarang dan saya tidak punya waktu untuk mengimplementasikan StaggeredGridLayoutManager dari awal (atau bahkan memperpanjang dari itu).
Saya masih mengujinya, tetapi Anda bisa mencobanya jika mau. Tolong beri tahu saya jika Anda menemukan masalah dengan itu.
sumber
Ada satu solusi lagi yang mencakup semua kasus penggunaan di atas: CompoundAdapter: https://github.com/negusoft/CompoundAdapter-android
Anda dapat membuat Adaptor Grup yang memegang Adaptor Anda apa adanya, bersama dengan adaptor dengan satu item untuk mewakili header. Kode ini mudah dan dapat dibaca:
AdapterGroup juga memungkinkan penyatuan, jadi untuk adaptor dengan bagian, Anda dapat membuat AdapterGroup per bagian. Kemudian letakkan semua bagian di root AdapterGroup.
sumber
HeaderView tergantung pada LayoutManager. Tidak ada LayoutManagers default yang mendukung ini dan mungkin tidak akan. HeaderView di ListView menciptakan banyak kerumitan tanpa manfaat signifikan.
Saya sarankan membuat kelas adaptor dasar yang menambahkan item untuk Header jika disediakan. Jangan lupa untuk mengganti metode notifikasi * untuk mengimbanginya dengan benar tergantung pada apakah header ada atau tidak.
sumber
ListView.addHeaderView
atau jawaban untuk pertanyaan ini.Setelah - Ganti metode getItemViewTpe *** Lebih Penting
metode onCreateViewHolder
metode onBindViewHolder
pada akhirnya mengimplementasikan statis kelas ViewHolders
sumber
berikut beberapa itemdecoration untuk recyclerview
sumber
Saya membuat implementasi berdasarkan @ hister untuk keperluan pribadi saya, tetapi menggunakan warisan.
Saya menyembunyikan mekanisme detail implementasi (seperti menambah 1 ke
itemCount
, mengurangi 1 dariposition
) dalam kelas super abstrakHeadingableRecycleAdapter
, dengan menerapkan metode yang diperlukan dari Adaptor sepertionBindViewHolder
,getItemViewType
dangetItemCount
, menjadikan metode itu final, dan menyediakan metode baru dengan logika tersembunyi kepada klien:onAddViewHolder(RecyclerView.ViewHolder holder, int position)
,onCreateViewHolder(ViewGroup parent)
,itemCount()
Inilah
HeadingableRecycleAdapter
kelas dan klien. Saya meninggalkan tata letak tajuk agak keras karena sesuai dengan kebutuhan saya.sumber
Mungkin membungkus header dan recyclerview ke dalam koordinatorlayout :
sumber
Mungkin http://alexzh.com/tutorials/multiple-row-layouts-using-recyclerview/ akan membantu. Hanya menggunakan RecyclerView dan CardView. Ini adaptornya:
Dan inilah entitas:
sumber
Anda bisa membuat addHeaderView dan menggunakannya
adapter.addHeaderView(View)
.Kode ini membangun
addHeaderView
lebih dari satu tajuk. header harus memiliki:android:layout_height="wrap_content"
sumber
Sudah beberapa tahun, tapi siapa tahu ada yang membaca ini nanti ...
Masalahnya adalah dalam deklarasi konstan:
Jika Anda mendeklarasikan keduanya sebagai nol, maka Anda akan selalu mendapatkan nol!
sumber
Saya telah menerapkan pendekatan yang sama yang diusulkan oleh jawaban EC84B4 , tapi saya mengabstraksi RecycleViewAdapter dan membuatnya mudah diresapi melalui antarmuka.
Jadi, untuk menggunakan pendekatan saya, Anda harus menambahkan kelas dasar dan antarmuka berikut ke proyek Anda:
1) Antarmuka yang menyediakan data untuk Adaptor (kumpulan tipe T generik, dan parameter tambahan (jika perlu) tipe P generik)
2) Pabrik untuk mengikat item Anda (header / item):
3) Pabrik untuk viewHolders (header / item):
4) Kelas dasar untuk Adaptor dengan Header:
Contoh penggunaan :
1) Implementasi IRecycleViewListHolder:
2) Implementasi IViewHolderBinderFactory:
3) Implementasi IViewHolderFactory:
4) Memperoleh adaptor
5) Instantiate kelas adaptor:
PS : AssetItemViewHolder, AssetBasedListItemBinding, dll. Struktur aplikasi saya sendiri yang harus ditukar oleh Anda sendiri, untuk keperluan Anda sendiri.
sumber