En-tête et pied de page de RecyclerView
peut-être cette question a-t-elle déjà été posée, mais je n'ai pas pu trouver de réponse ou de solution précise. J'ai commencé à utiliser le RecyclerView, et je l'ai implémenté en utilisant le Gestionnaire de lignes. Maintenant, je veux ajouter des éléments d'en-tête et de pied de page personnalisés, qui diffèrent du reste des éléments dans mon RecyclerView. L'en-tête et le pied de page ne doivent pas être collants, je veux qu'ils fassent défiler avec le reste des articles. Quelqu'un peut-il nous montrer un exemple ou simplement nous faire part de ses idées? Je vous en seront reconnaissants très bien. Thx
10 réponses
dans votre adaptateur, ajouter cette classe:
private class VIEW_TYPES {
public static final int Header = 1;
public static final int Normal = 2;
public static final int Footer = 3;
}
modifier ensuite la méthode suivante comme ceci:
@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;
}
maintenant dans la méthode onCreateViewHolder gonfler votre mise en page basée sur le type de vue::
@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);
}
j'Espère que cela peut aider.
c'est très facile avec Itemdécorations et sans modifier aucun autre code:
recyclerView.addItemDecoration(new HeaderDecoration(this,
recyclerView, R.layout.test_header));
réserver un peu d'espace pour le dessin, gonfler la mise en page que vous voulez dessiner et le dessiner dans l'espace réservé.
le code de la décoration:
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();
}
}
}
vous pouvez utiliser cette bibliothèque GitHub] pour ajouter un en-tête ou un pied de page à votre RecyclerView
de la manière la plus simple possible.
vous devez ajouter le HFRecyclerView bibliothèque dans votre projet ou vous pouvez également l'attraper de Gradle:
compile 'com.mikhaellopez:hfrecyclerview:1.0.0'
cette bibliothèque est basée sur un travail à @hister
C'est un résultat en image:
cliquez sur ici . J'ai fait une extension de RecyclerView.Adaptateur. Facile à ajouter en-tête et pied de page.
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();
pour les en-têtes linéaires sectionnées avec GridView articles dans Recyclerview: -
je suggère de ne pas personnaliser l'adaptateur rv.
gardez-le comme il est...dans votre disposition d'article de rv il suffit d'ajouter le pied de page avec la mise en page et de mettre la visisbilty disparu.
ensuite, lorsque vous atteignez le dernier article dans Adaptateur...rendre visible.
et quand vous essayez cela, assurez-vous d'ajouter ceci à votre adaptateur rv.
@Override
public void onBindViewHolder(final PersonViewHolder personViewHolder, int i) {
if(i==List.size()) // Last item in recycle view
personViewHolder.tv_footer.setVisibility(VISIBLE);// Make footer visible now }
@Override
public int getItemViewType(int position) {
return position;
}
Faire la même chose pour l'en-Tête. Ici i= = 0 / / premier élément de la liste
la solution la plus facile pour moi.
peut être GroupAdapter est ce que vous voulez.
spécialisé RecyclerView.Adaptateur qui présente les données d'une séquence de RecyclerView.Adaptateur. La séquence est statique, mais chaque adaptateur peut être présenté en zéro ou plusieurs points de vue. L'adaptateur enfant peut utiliser ViewType en toute sécurité. De plus, nous pouvons ajouter headerview ou addFooterView comme ListView.
vous pouvez utiliser la bibliothèque SectionedRecyclerViewAdapter , il a le concept de" Sections", où quelle Section a un en-tête, pied de page et le contenu (liste des éléments). Dans votre cas, vous pourriez n'avoir besoin que D'une Section, mais vous pouvez en avoir plusieurs:
1) Créer une classe de section personnalisée:
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) Créer un afficheur personnalisé pour les articles:
class MyItemViewHolder extends RecyclerView.ViewHolder {
private final TextView tvItem;
public MyItemViewHolder(View itemView) {
super(itemView);
tvItem = (TextView) itemView.findViewById(R.id.tvItem);
}
}
3) configurer votre ReclyclerView avec la Sectionrecyclerviewadapter
// 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);
voici quelques en-tête Decoration Pour recyclerview
avec une modification partielle vous pouvez changer en pied de page
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();
}
}
}
une autre façon serait d'envelopper en-tête et reyclerview dans un coordinatorlayout :
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<View
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />