Заголовок и нижний колонтитул RecyclerView

Возможно, этот вопрос задавали раньше, но я не мог найти точного ответа или решения. Я начал использовать 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 раздуйте ваш макет на основе типа вида ::

 @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(); 

Может быть, GroupAdapter – это то, что вы хотите.

Специализированный RecyclerView.Adapter, который представляет данные из последовательности RecyclerView.Adapter. Последовательность статична, но каждый адаптер может быть представлен в виде ноль или нескольких позиций. Ребенок-адаптер может безопасно использовать ViewType. Кроме того, мы можем добавитьHeaderView или addFooterView, например ListView.

Вы можете использовать библиотеку SectionedRecyclerViewAdapter , она имеет концепцию «Разделы», где у Секции есть Заголовок, Нижний колонтитул и Контент (список элементов). В вашем случае вам может понадобиться только один раздел, но у вас может быть много:

Введите описание изображения здесь

1) Создайте собственный класс класса:

 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) Создайте пользовательский ViewHolder для элементов:

 class MyItemViewHolder extends RecyclerView.ViewHolder { private final TextView tvItem; public MyItemViewHolder(View itemView) { super(itemView); tvItem = (TextView) itemView.findViewById(R.id.tvItem); } } 

3) Настройте свой ReclyclerView с помощью SectionedRecyclerViewAdapter

 // 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); 

Для разделенных заголовков LinearView с элементами GridView в Recyclerview: –

Проверьте SectionedGridRecyclerViewAdapter

Введите описание изображения здесь

Здесь некоторые заголовок itemdecoration для recycliewiew

С некоторой модификацией вы можете перейти на нижний колонтитул

 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(); } } } 

Я бы предложил не настраивать адаптеры rv.

Держите его так, как … в макете rv-элементов просто добавьте нижний колонтитул с макетом и установите visisbilty.

Затем, когда вы достигнете последнего элемента в адаптере … сделайте его видимым.

И когда вы попробуете это, убедитесь, что вы добавили это в свой rv-адаптер. @Override public int getItemViewType (int position) {return position; }

Простое решение огромной проблемы.