この質問は以前に聞かれたかもしれませんが、正確な答えや解決策を見つけることができなかったようです。 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);
}
OnBindViewHolderメソッドで、ビューホルダーに基づいてレイアウトをバインドします。
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
int viewType = getItemViewType(position);
switch(viewType) {
case VIEW_TYPES.Header: // handle row header
break;
case VIEW_TYPES.Footer: // handle row footer
break;
case VIEW_TYPES.Normal: // handle row item
break;
}
}
これが役立つことを願っています。
これは、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 の作品に基づいています
これはイメージの結果です:
here をクリックします。 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();
Rv adapaterをカスタマイズしないことをお勧めします。
そのままにして... rvアイテムのレイアウトで、レイアウトにフッターを追加して、visisbiltyを設定します。
次に、アダプタの最後のアイテムに到達したら...それを表示します。
これを試すときは、これを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;
}
ヘッダーにも同じことを行います。ここでi == 0 //リストの最初のアイテム
私にとって最も簡単な解決策。
もう1つの方法は、ヘッダーとreyclerviewを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" />
GroupAdapter が必要な場合があります。
一連のRecyclerView.Adapterからのデータを提示する特殊なRecyclerView.Adapter。シーケンスは静的ですが、各アダプターは0個以上のアイテムビューで表示できます。子アダプターはViewTypeを安全に使用できます。さらに、ListViewと同様にaddHeaderViewまたはaddFooterViewを使用できます。
必要なものが空白のヘッダーとフッターだけである場合、これを実現する非常に簡単な方法を以下に示します(Kotlinで記述):
class HeaderFooterDecoration(private val headerHeight: Int, private val footerHeight: Int) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
val adapter = parent.adapter ?: return
when (parent.getChildAdapterPosition(view)) {
0 -> outRect.top = headerHeight
adapter.itemCount - 1 -> outRect.bottom = footerHeight
else -> outRect.set(0, 0, 0, 0)
}
}
}
次のように呼び出します:
recyclerView.addItemDecoration(HeaderFooterDecoration(headerHeightPx, footerHeightPx))
ここにrecyclerviewのヘッダーアイテム装飾があります
フッターに変更できる多少の修正が必要
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();
}
}
}
ライブラリ 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));
}
}
class MyItemViewHolder extends RecyclerView.ViewHolder {
private final TextView tvItem;
public MyItemViewHolder(View itemView) {
super(itemView);
tvItem = (TextView) itemView.findViewById(R.id.tvItem);
}
}
// 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);