How to implement RecyclerView with section header depending on category?

前端 未结 4 1772
傲寒
傲寒 2020-12-25 15:12

I want to implement sections in my list. I have a list of tasks. List has a custom adapter which extends recyclerview swipe adapter as I have implemented swipe gesture to th

相关标签:
4条回答
  • 2020-12-25 15:46

    Take a look at my library on Github, can be used to easily create sections: RecyclerAdapter & Easy Section

    mRecylerView.setLayoutManager(...);
    /*create Adapter*/
    RecyclerAdapter<Customer> baseAdapter = new RecyclerAdapter<>(...);
    /*create sectioned adapter. the Adapter type can be RecyclerView.Adapter*/
    SectionedAdapter<String, RecyclerAdapter> adapter = new SectionedAdapter<>(SectionViewHolder.class, baseAdapter);
    /*add your sections*/
    sectionAdapter.addSection(0/*position*/, "Title Section 1");
    /*attach Adapter to RecyclerView*/
    mRecylerView.setAdapter(sectionAdapter);
    

    Hope it helps.

    0 讨论(0)
  • 2020-12-25 15:49

    You can implement it with the library SectionedRecyclerViewAdapter as I explained in this post.

    In order to implement the SwipeLayout, don't extend RecyclerSwipeAdapter, extend SectionedRecyclerViewAdapter and implement the SwipeLayout in ItemViewHolder / onBindItemViewHolder as you have done.

    0 讨论(0)
  • 2020-12-25 15:55

    The most simple way to split your recycler view into sections is by using a layout with the header and the item already in place and then changing the visibility if the header is the same.

    Layout:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <TextView
            android:id="@+id/tvHeader"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:padding="16dp"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="@color/primary"
            android:textStyle="bold"
            tools:text="A" />
    
        <TextView
            android:id="@+id/tvName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/tvHeader"
            android:background="?android:attr/selectableItemBackground"
            android:padding="16dp"
            android:textAppearance="?android:attr/textAppearanceMedium"
            tools:text="Adam" />
    
    </RelativeLayout>
    

    Adapter (2018 Kotlin Edition):

    class ContactAdapter @Inject constructor() : RecyclerView.Adapter<ContactAdapter.ViewHolder>() {
    
        var onItemClick: ((Contact) -> Unit)? = null
        var contacts = emptyList<Contact>()
    
        override fun getItemCount(): Int {
            return contacts.size
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_contact, parent, false))
        }
    
        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            val name = contacts[position].name
            holder.header.text = name.substring(0, 1)
            holder.name.text = name
    
            // if not first item, check if item above has the same header
            if (position > 0 && contacts[position - 1].name.substring(0, 1) == name.substring(0, 1)) {
                holder.headerTextView.visibility = View.GONE
            } else {
                holder.headerTextView.visibility = View.VISIBLE
            }
        }
    
        inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            val headerTextView: TextView = itemView.tvHeader
            val nameTextView: TextView = itemView.tvName
    
            init {
                itemView.setOnClickListener {
                    onItemClick?.invoke(contacts[adapterPosition])
                }
            }
        }
    }
    


    Might be helpful as well: RecyclerView itemClickListener in Kotlin



    Old Java Adapter Version:

    public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.DataViewHolder> {
    
        private List<Contact> mData;
    
        @Inject
        public RecyclerAdapter() {
            mData = new ArrayList<>();
        }
    
        public void setData(List<Contact> data) {
            mData = data;
        }
    
        public Contact getItem(int position){
            return mData.get(position);
        }
    
        @Override
        public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_contact, parent, false);
            return new DataViewHolder(itemView);
        }
    
        @Override
        public void onBindViewHolder(final DataViewHolder holder, int position) {
            Contact contact = mData.get(position);
            holder.headerTextView.setText(contact.getName().substring(0, 1));
            holder.nameTextView.setText(contact.getName());
    
            // if not first item check if item above has the same header
            if (position > 0 && mData.get(position - 1).getName().substring(0, 1).equals(contact.getName().substring(0, 1))) {
                holder.headerTextView.setVisibility(View.GONE);
            } else {
                holder.headerTextView.setVisibility(View.VISIBLE);
            }
        }
    
        @Override
        public int getItemCount() {
            return mData.size();
        }
    
        public class DataViewHolder extends RecyclerView.ViewHolder {
    
            @BindView(R.id.text_header)
            TextView headerTextView;
            @BindView(R.id.text_name)
            TextView nameTextView;
    
            public DataViewHolder(View itemView) {
                super(itemView);
                ButterKnife.bind(this, itemView);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-25 15:58

    You can do it youself by hard codding.There ar smart ways to do this. follow these links. and choose one for you.

    https://github.com/afollestad/sectioned-recyclerview https://github.com/truizlop/SectionedRecyclerView http://android-pratap.blogspot.in/2015/12/sectioned-recyclerview-in-android_1.html

    You can search more by "sectioned recyclerViews android libraries"

    0 讨论(0)
提交回复
热议问题