I\'m looking for an equivalent to addHeaderView for a recycler view. Basically I want to have an image with 2 buttons be added as a header to the listview. Is there a differ
Feel free to use my library, available here.
It let's you create header View
for any RecyclerView
that uses LinearLayoutManager
or GridLayoutManager
with just a simple method call.
It's been a few years, but just in case anyone is reading this later...
Using the above code, only the header layout is displayed as viewType is always 0.
The problem is in the constant declaration:
private static final int HEADER = 0;
private static final int OTHER = 0; <== bug
If you declare them both as zero, then you'll always get zero!
Native API doesn't have such "addHeader" feature, but has the concept of "addItem".
I was able to include this specific feature of headers and extends for footers as well in my FlexibleAdapter project. I called it Scrollable Headers and Footers.
Here how they work:
Scrollable Headers and Footers are special items that scroll along with all others, but they don't belongs to main items (business items) and they are always handled by the adapter beside the main items. Those items are persistently located at the first and last positions.
There's a lot to say about them, better to read the detailed wiki page.
Moreover the FlexibleAdapter allows you to create headers/sections, also you can have them sticky and tens of others features like expandable items, endless scroll, UI extensions etc... all in one library!
First - extends RecyclerView.Adapter<RecyclerView.ViewHolder>
public class MenuAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
After - Override the method getItemViewTpe ***More Important
@Override
public int getItemViewType(int position) {
return position;
}
method onCreateViewHolder
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.menu_item, parent, false);
View header = LayoutInflater.from(parent.getContext()).inflate(R.layout.menu_header_item, parent, false);
Log.d("onCreateViewHolder", String.valueOf(viewType));
if (viewType == 0) {
return new MenuLeftHeaderViewHolder(header, onClickListener);
} else {
return new MenuLeftViewHolder(view, onClickListener);
}
}
method onBindViewHolder
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (position == 0) {
MenuHeaderViewHolder menuHeaderViewHolder = (MenuHeaderViewHolder) holder;
menuHeaderViewHolder.mTitle.setText(sMenuTitles[position]);
menuHeaderViewHolder.mImage.setImageResource(sMenuImages[position]);
} else {
MenuViewHolder menuLeftViewHolder = (MenuLeftViewHolder) holder;
menuViewHolder.mTitle.setText(sMenuTitles[position]);
menuViewHolder.mImage.setImageResource(sMenuImages[position]);
}
}
in finish implements the ViewHolders class static
public static class MenuViewHolder extends RecyclerView.ViewHolder
public static class MenuLeftHeaderViewHolder extends RecyclerView.ViewHolder
There is one more solution that covers all the use cases above: CompoundAdapter: https://github.com/negusoft/CompoundAdapter-android
You can create a AdapterGroup that holds your Adapter as it is, along with an adapter with a single item to represent the header. The code is easy and readable:
AdapterGroup adapterGroup = new AdapterGroup();
adapterGroup.addAdapter(SingleAdapter.create(R.layout.header));
adapterGroup.addAdapter(new CommentAdapter(...));
recyclerView.setAdapter(adapterGroup);
AdapterGroup allows nesting too, so for a adapter with sections, you may create a AdapterGroup per section. Then put all the sections in a root AdapterGroup.
HeaderView depends on the LayoutManager. None of the default LayoutManagers support this and probably wont. HeaderView in ListView creates a lot of complexity without any significant benefit.
I would suggest creating a base adapter class that adds items for Headers if provided. Don't forget to override notify* methods to offset them properly depending on whether header is present or not.