RecyclerView页眉和页脚
也许这个问题之前已经被问过了,但我似乎无法find一个确切的答案或解决scheme。 我开始使用RecyclerView,并使用LinearLayoutManager实现它。 现在我想添加自定义页眉和页脚项目,这与我的RecyclerView中的其余项目不同。 页眉和页脚不应该粘,我希望他们滚动其余的项目。 有人可以指出一些例子如何做到这一点或只是分享想法。 我会非常感激。 谢谢
在你的适配器中添加这个类:
private class VIEW_TYPES { public static final int Header = 1; public static final int Normal = 2; public static final int Footer = 3; }
然后重写下面的方法:
@Override public int getItemViewType(int position) { if(items.get(position).isHeader) return VIEW_TYPES.Header; else if(items.get(position).isFooter) return VIEW_TYPES.Footer; else return VIEW_TYPES.Normal; }
现在在onCreateViewHolder方法膨胀你的布局基于视图types::
@Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View rowView; switch (i) { case VIEW_TYPES.Normal: rowView=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.normal, viewGroup, false); break; case VIEW_TYPES.Header: rowView=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.header, viewGroup, false); break; case VIEW_TYPES.Footer: rowView=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.footer, viewGroup, false); break; default: rowView=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.normal, viewGroup, false); break; } return new ViewHolder (rowView); }
希望这可以帮助。
ItemDecorations非常简单,不需要修改任何其他代码:
recyclerView.addItemDecoration(new HeaderDecoration(this, recyclerView, R.layout.test_header));
保留一些绘制空间,膨胀你想绘制的布局,并在保留空间中绘制。
装饰的代码:
public class HeaderDecoration extends RecyclerView.ItemDecoration { private View mLayout; public HeaderDecoration(final Context context, RecyclerView parent, @LayoutRes int resId) { // inflate and measure the layout mLayout = LayoutInflater.from(context).inflate(resId, parent, false); mLayout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); // layout basically just gets drawn on the reserved space on top of the first view mLayout.layout(parent.getLeft(), 0, parent.getRight(), mLayout.getMeasuredHeight()); for (int i = 0; i < parent.getChildCount(); i++) { View view = parent.getChildAt(i); if (parent.getChildAdapterPosition(view) == 0) { c.save(); final int height = mLayout.getMeasuredHeight(); final int top = view.getTop() - height; c.translate(0, top); mLayout.draw(c); c.restore(); break; } } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { if (parent.getChildAdapterPosition(view) == 0) { outRect.set(0, mLayout.getMeasuredHeight(), 0, 0); } else { outRect.setEmpty(); } } }
您可以使用此GitHub库以最简单的方式向您的RecyclerView
添加页眉或页脚。
您需要在您的项目中添加HFRecyclerView库,或者您也可以从Gradle中获取:
compile 'com.mikhaellopez:hfrecyclerview:1.0.0'
这个库基于@hister的工作
这是形象的结果:
点击这里 。 我做了RecyclerView.Adapter的扩展。 轻松添加页眉和页脚。
class HFAdapter extends HFRecyclerViewAdapter<String, HFAdapter.DataViewHolder>{ public HFAdapter(Context context) { super(context); } @Override public DataViewHolder onCreateDataItemViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.data_item, parent, false); return new DataViewHolder(v); } @Override public void onBindDataItemViewHolder(DataViewHolder holder, int position) { holder.itemTv.setText(getData().get(position)); } class DataViewHolder extends RecyclerView.ViewHolder{ TextView itemTv; public DataViewHolder(View itemView) { super(itemView); itemTv = (TextView)itemView.findViewById(R.id.itemTv); } } } //add header View headerView = LayoutInflater.from(this).inflate(R.layout.header, recyclerView, false); hfAdapter.setHeaderView(headerView); //add footer View footerView = LayoutInflater.from(this).inflate(R.layout.footer, recyclerView, false); hfAdapter.setFooterView(footerView); //remove hfAdapter.removeHeader(); hfAdapter.removeFooter();
对于在Recyclerview中使用GridView项目的分段LinearView标题: –
检查SectionedGridRecyclerViewAdapter
可能是GroupAdapter是你想要的。
一个专门的RecyclerView.Adapter,用于显示RecyclerView.Adapter序列中的数据。 序列是静态的,但每个适配器可以呈现在零个或多个项目视图中。 子适配器可以安全地使用ViewType。 另外,我们可以像添加ListView一样添加HeaderView或者AddFooterView。
您可以使用库SectionedRecyclerViewAdapter ,它具有“部分”的概念,其中部分具有页眉,页脚和内容(项目列表)。 在你的情况下,你可能只需要一个部分,但你可以有很多:
1)创build一个自定义的Section类:
class MySection extends StatelessSection { List<String> myList = Arrays.asList(new String[] {"Item1", "Item2", "Item3" }); public MySection() { // call constructor with layout resources for this Section header, footer and items super(R.layout.section_header, R.layout.section_footer, R.layout.section_item); } @Override public int getContentItemsTotal() { return myList.size(); // number of items of this section } @Override public RecyclerView.ViewHolder getItemViewHolder(View view) { // return a custom instance of ViewHolder for the items of this section return new MyItemViewHolder(view); } @Override public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) { MyItemViewHolder itemHolder = (MyItemViewHolder) holder; // bind your view here itemHolder.tvItem.setText(myList.get(position)); } }
2)为这些项目创build一个自定义的ViewHolder:
class MyItemViewHolder extends RecyclerView.ViewHolder { private final TextView tvItem; public MyItemViewHolder(View itemView) { super(itemView); tvItem = (TextView) itemView.findViewById(R.id.tvItem); } }
3)用SectionedRecyclerViewAdapter设置您的ReclyclerView
// Create an instance of SectionedRecyclerViewAdapter SectionedRecyclerViewAdapter sectionAdapter = new SectionedRecyclerViewAdapter(); MySection mySection = new MySection(); // Add your Sections sectionAdapter.addSection(mySection); // Set up your RecyclerView with the SectionedRecyclerViewAdapter RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setAdapter(sectionAdapter);
我会build议不要自定义rv adapater。
把它保存为…在你的RV项目布局只是添加页脚的布局,并设置可见性消失。
然后,当你到达适配器的最后一个项目…使其可见。
当你尝试这个时,确保你把它添加到你的rv适配器。 @Override public int getItemViewType(int position){return position; }
最简单的解决scheme一个巨大的问题。
这里有一些用于recyclerview的标题itemdecoration
有一些修改,你可以改变页脚
public class HeaderItemDecoration extends RecyclerView.ItemDecoration { private View customView; public HeaderItemDecoration(View view) { this.customView = view; } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); customView.layout(parent.getLeft(), 0, parent.getRight(), customView.getMeasuredHeight()); for (int i = 0; i < parent.getChildCount(); i++) { View view = parent.getChildAt(i); if (parent.getChildAdapterPosition(view) == 0) { c.save(); final int height = customView.getMeasuredHeight(); final int top = view.getTop() - height; c.translate(0, top); customView.draw(c); c.restore(); break; } } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { if (parent.getChildAdapterPosition(view) == 0) { customView.measure(View.MeasureSpec.makeMeasureSpec(parent.getMeasuredWidth(), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(parent.getMeasuredHeight(), View.MeasureSpec.AT_MOST)); outRect.set(0, customView.getMeasuredHeight(), 0, 0); } else { outRect.setEmpty(); } } }