這是一個(gè)繼承自recyclerView欠拾,并且修改的recyclerView
支持頭尾添加,滾動(dòng)到尾部監(jiān)聽骗绕,方法鏈?zhǔn)秸{(diào)用藐窄。在瀑布流,Gird的形態(tài)下酬土,頭尾依然單獨(dú)占用一行荆忍,已經(jīng)做了修正
將這個(gè)自定義recyclerview的java文件放到你的項(xiàng)目里,就可以開始用了
如何使用
1.文章的最下方拷貝recycleView的代碼到你的項(xiàng)目里撤缴。
2.在布局里引用
<你的包名.PerfectRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"></你的包名.PerfectRecyclerView>
3.代碼中使用
1.
PerfectRecyclerView mRecyclerView = (PerfectRecyclerView) findViewById(R.id.recyclerView);
2.
//一個(gè)正常RecyclerView adapter 下方有這個(gè)adapter代碼
RvAdapter rvAdapter = new RvAdapter();
//初始化刹枉,然后全程鏈?zhǔn)秸{(diào)用,注意調(diào)用順序
//1.設(shè)置容器 2.設(shè)置adapter
// 頭尾隨意使用
mRecyclerView.
/**
* 設(shè)置容器
* 豎的list
* setLayoutManagerVerticalLinear()
* 橫的list
* .setLayoutManagerHorizontalLinear()
* 豎的Grid
* setLayoutManagerVerticalGird(int行數(shù))
* 橫的Grid
* setLayoutManagerHorizontalGird(int行數(shù))
* 豎 瀑布流
* setLayoutManagerVerticalStaggered(int行數(shù))
* 橫 瀑布流
* setLayoutManagerHorizontalStaggered(int行數(shù))
*/
//設(shè)置adapter
.setAdapterPerfect(rvAdapter)
/**
*注意:如果添加了頭布局屈呕,
*那么ViewHolder內(nèi)的getPosition()方法返回的是position+1微宝,正確需要getPosition()-1
*getAdapterPosition() 將返回你的adapter內(nèi)的 position,所以假如調(diào)用刷新虎眨,需要 *getAdapterPosition()+1
*/
//添加頭布局
.addHeaderView(R.layout.header_view)
//添加腳布局
.addFooterView(R.layout.footer_view)
//滾動(dòng)到腳布局監(jiān)聽
.addScrollBottom(new PerfectRecyclerView.OnScrollBottom() {
@Override
public void scrollBottom() {
//滑動(dòng)到底部監(jiān)聽
//這里注意:對(duì)list進(jìn)行判斷
if (list != null && list.size() > 0) {
//加載數(shù)據(jù)蟋软,然后刷新
(注意:原notifyDataSetChanged()等一系列刷新方法已經(jīng)改變,下
方有說明)
}
}
});
////////////////////////////////////////////////////////////////////////////////////////
/**
*完整示例
*/
mRecyclerView.setLayoutManagerVerticalLinear()
.setAdapterPerfect(adapter)
.addHeaderView(R.layout.header)
.addFooterView(R.layout.foot)
.addScrollBottom(new PerfectRecyclerView.OnScrollBottom() {
@Override
public void scrollBottom() {
}
});
////////////////////////////////////////////////////////////////////////////////////////
/**
* 一些返回方法
*/
//返回容器
RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager();
//返回頭布局view
View header = mRecyclerView.getHeaderParent();
//使用這個(gè)header進(jìn)行findViewById你的布局內(nèi)的子view
//舉例
TextView tv = header.findViewById(R.id.tv1);
//返回為腳布局view 同頭布局一樣
View footer = mRecyclerView.getFooterParent();
正常的RecyclerView Apapter
//和正常的adapter一樣
class RvAdapter extends RecyclerView.Adapter<RvAdapter.RvHolder > {
@Override
public RvHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new RvHolder (LayoutInflater.from(parent.getContext()).inflate(R.layout.dialog_gallery, parent, false));
}
@Override
public void onBindViewHolder(RvHolder holder, int position) {
//無論你添加了頭尾嗽桩,這里的position都是的正確的position
holder.tv.setText(list.get(position));
}
@Override
public int getItemCount() {
return list == null ? 0 : list.size();
}
class RvHolder extends RecyclerView.ViewHolder {
private TextView tv;
public RvHolder (View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.tv1);
}
}
}
提供一個(gè)稍微簡易的adapter岳守,將它復(fù)制到你的項(xiàng)目里
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
public abstract class PerfectAdapter<T extends RecyclerView.ViewHolder, E> extends RecyclerView.Adapter<T> {
private int layout;
private List<E> list;
public PerfectAdapter(List<E> list, int layout) {
this.list = list;
this.layout = layout;
}
@Override
public T onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(layout, viewGroup, false);
return getHolder(view);
}
protected abstract T getHolder(View view);
@Override
public void onBindViewHolder(T t, int position) {
E bean = list.get(position);
bindView(t, position, bean);
}
protected abstract void bindView(T t, int position, E bean);
@Override
public int getItemCount() {
return list == null ? 0 : list.size();
}
}
如何使用這個(gè)簡易adapter
//1.先寫一個(gè)viewholder
class RvHolder extends RecyclerView.ViewHolder {
private TextView tv;
public RvHolder (View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.tv1);
}
}
//2.使用這個(gè)簡易的adapter
BaseRvAdapter rvAdapter = new BaseRvAdapter<RvHolder, JavaBean>(list,R.layout.item) {
@Override
protected RvHolder getHolder(View view) {
return new RvHolder(view);
}
@Override
protected void bindView(RvHolder rvHolder, int position, JavaBean bean) {
//無論你添加了頭尾,這里的position都是的正確的position
rvHolder.tv.setText(bean);
}
};
注意
刷新方法不再是你的 adapter.notifyDataSetChanged()
調(diào)用這個(gè)方法將不會(huì)再刷新你的RecyclerView
正確的刷新方法請(qǐng)使用
//全局刷新
mRecyclerView.notifyDataSetChanged();
//某條目刷新
mRecyclerView.notifyItemChanged(int);
//插入某條目
mRecyclerView.notifyItemInserted(int);
//刪除某條目
mRecyclerView.notifyItemRemoved(int);
ViewHolder內(nèi)的getPosition()與getAdapterPosition() 方法使用注意
如果你添加了頭布局碌冶,
當(dāng)你需要刷新某一條時(shí)候
那么正確的 getPosition() = getPosition()-1
正確的getAdapterPosition() = getAdapterPosition()+1
這里是這個(gè)RecyclerView的源碼湿痢,復(fù)制到你的項(xiàng)目里就可以使用了
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class PerfectRecyclerView extends RecyclerView {
private View mHeaderView;
private View mFooterView;
private PerfectAdapter perfectAdapter;
private Context context;
private boolean loadMoreSwitch = true;
public PerfectRecyclerView(Context context) {
super(context);
}
public PerfectRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public PerfectRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
}
public PerfectRecyclerView addHeaderView(@LayoutRes int id) {
mHeaderView = LayoutInflater.from(getContext()).inflate(id, this, false);
perfectAdapter.notifyItemInserted(0);
return this;
}
public PerfectRecyclerView addFooterView(@LayoutRes int id) {
mFooterView = LayoutInflater.from(getContext()).inflate(id, this, false);
perfectAdapter.notifyItemInserted(perfectAdapter.getItemCount() - 1);
return this;
}
public void closeLoadMore() {
loadMoreSwitch = false;
}
public View getFooterParent() {
return mFooterView;
}
public View getHeaderParent() {
return mHeaderView;
}
public void notifyItemInserted(int i) {
if (mHeaderView != null) i++;
perfectAdapter.notifyItemInserted(i);
}
public void notifyItemChanged(int i) {
if (mHeaderView != null) i++;
perfectAdapter.notifyItemChanged(i);
}
public void notifyItemRemoved(int i) {
if (mHeaderView != null) i++;
perfectAdapter.notifyItemRemoved(i);
}
public void notifyDataSetChanged() {
perfectAdapter.notifyDataSetChanged();
}
@Deprecated
@Override
public void setAdapter(Adapter adapter) {
if (adapter != null) {
perfectAdapter = new PerfectAdapter(adapter);
}
super.setAdapter(perfectAdapter);
}
public PerfectRecyclerView setAdapterPerfect(Adapter adapter) {
this.setAdapter(adapter);
return this;
}
@Override
public void onScrolled(int dx, int dy) {
super.onScrolled(dx, dy);
if (onRollingRequestMore != null) {
if (isSlideToBottom() && loadMoreSwitch) {
onRollingRequestMore.scrollBottom();
}
}
}
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
if (((RecyclerView) target).getChildAt(0).getY() == 0) {
scollTop.isScollTop();
}
super.onNestedPreScroll(target, dx, dy, consumed);
}
private ScollTop scollTop;
public PerfectRecyclerView scollTop(ScollTop scollTop) {
this.scollTop = scollTop;
return this;
}
public interface ScollTop {
void isScollTop();
}
//VerticalLinear
public PerfectRecyclerView setLayoutManagerVerticalLinear() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
layoutManager = linearLayoutManager;
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
this.setLayoutManager(linearLayoutManager);
return this;
}
//HorizontalLinear
public PerfectRecyclerView setLayoutManagerHorizontalLinear() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
layoutManager = linearLayoutManager;
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
this.setLayoutManager(linearLayoutManager);
return this;
}
//VerticalGird
public PerfectRecyclerView setLayoutManagerVerticalGird(int i) {
GridLayoutManager gridLayoutManager = new GridLayoutManager(context, i);
gridLayoutManager.setOrientation(GridLayoutManager.VERTICAL);
layoutManager = gridLayoutManager;
this.setLayoutManager(gridLayoutManager);
return this;
}
//HorizontalGird
public PerfectRecyclerView setLayoutManagerHorizontalGird(int i) {
GridLayoutManager gridLayoutManager = new GridLayoutManager(context, i);
gridLayoutManager.setOrientation(GridLayoutManager.HORIZONTAL);
layoutManager = gridLayoutManager;
this.setLayoutManager(gridLayoutManager);
return this;
}
//VerticalStaggeredGrid
public PerfectRecyclerView setLayoutManagerVerticalStaggered(int i) {
StaggeredGridLayoutManager sgl = new StaggeredGridLayoutManager(i, StaggeredGridLayoutManager.VERTICAL);
layoutManager = sgl;
this.setLayoutManager(sgl);
return this;
}
/**
* 平行瀑布流
*
* @param i 垂直每行 i 條
* @return
*/
public PerfectRecyclerView setLayoutManagerHorizontalStaggered(int i) {
StaggeredGridLayoutManager sgl = new StaggeredGridLayoutManager(i, StaggeredGridLayoutManager.HORIZONTAL);
layoutManager = sgl;
this.setLayoutManager(sgl);
return this;
}
private LayoutManager layoutManager;
/**
* @return LayoutManager
*/
public LayoutManager getLayoutManager() {
return layoutManager;
}
OnScrollBottom onRollingRequestMore;
/**
* 滑動(dòng)到底部監(jiān)聽
*
* @param onBottomLoad
*/
public void addScrollBottom(OnScrollBottom onBottomLoad) {
this.onRollingRequestMore = onBottomLoad;
}
public interface OnScrollBottom {
void scrollBottom();
}
protected boolean isSlideToBottom() {
if (computeVerticalScrollExtent() + computeVerticalScrollOffset() >= computeVerticalScrollRange())
return true;
return false;
}
private class PerfectAdapter extends Adapter<ViewHolder> {
private Adapter adapter;
private int Item_Normal = 0;
private int Item_Header = 1;
private int Item_Footer = 2;
public PerfectAdapter(Adapter adapter) {
this.adapter = adapter;
}
@Override
public void onViewAttachedToWindow(ViewHolder holder) {
super.onViewAttachedToWindow(holder);
if (isStaggeredGridLayout(holder)) {
handleLayoutIfStaggeredGridLayout(holder, holder.getLayoutPosition());
}
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
LayoutManager manager = recyclerView.getLayoutManager();
if (manager instanceof GridLayoutManager) {
final GridLayoutManager gridManager = ((GridLayoutManager) manager);
gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return getItemViewType(position) == Item_Footer | getItemViewType(position) == Item_Header ? gridManager.getSpanCount() : 1;
}
});
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == Item_Header) {
return new PerfectViewHolder(mHeaderView);
} else if (viewType == Item_Footer) {
return new PerfectViewHolder(mFooterView);
} else {
return adapter.onCreateViewHolder(parent, viewType);
}
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
int type = getItemViewType(position);
if (type == Item_Header || type == Item_Footer) {
return;
}
int realPosition = getRealItemPosition(position);
adapter.onBindViewHolder(holder, realPosition);
}
@Override
public int getItemCount() {
int itemCount = adapter.getItemCount();
if (null != mHeaderView) itemCount++;
if (null != mFooterView) itemCount++;
return itemCount;
}
@Override
public int getItemViewType(int position) {
if (null != mHeaderView && position == 0) return Item_Header;
if (null != mFooterView && position == getItemCount() - 1) return Item_Footer;
return Item_Normal;
}
private boolean isStaggeredGridLayout(ViewHolder holder) {
ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
if (layoutParams != null && layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
return true;
}
return false;
}
protected void handleLayoutIfStaggeredGridLayout(ViewHolder holder, int position) {
if (getItemViewType(position) == Item_Footer | getItemViewType(position) == Item_Header) {
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
p.setFullSpan(true);
}
}
private int getRealItemPosition(int position) {
if (null != mHeaderView) {
return position - 1;
}
return position;
}
private class PerfectViewHolder extends ViewHolder {
PerfectViewHolder(View itemView) {
super(itemView);
}
}
}
}