使用起来超级方便的RecyclerView,支持头尾,滚动到尾部
2017-03-27 本文已影响409人
丶dtdsn
这是一个继承自recyclerView,并且修改的recyclerView
支持头尾添加,滚动到尾部监听,方法链式调用。在瀑布流,Gird的形态下,头尾依然单独占用一行,已经做了修正
将这个自定义recyclerview的java文件放到你的项目里,就可以开始用了
图片如何使用
1.文章的最下方拷贝recycleView的代码到你的项目里。
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.
//一个正常RecyclerView adapter 下方有这个adapter代码
RvAdapter rvAdapter = new RvAdapter();
//初始化,然后全程链式调用,注意调用顺序
//1.设置容器 2.设置adapter
// 头尾随意使用
mRecyclerView.
/**
* 设置容器
* 竖的list
* setLayoutManagerVerticalLinear()
* 横的list
* .setLayoutManagerHorizontalLinear()
* 竖的Grid
* setLayoutManagerVerticalGird(int行数)
* 横的Grid
* setLayoutManagerHorizontalGird(int行数)
* 竖 瀑布流
* setLayoutManagerVerticalStaggered(int行数)
* 横 瀑布流
* setLayoutManagerHorizontalStaggered(int行数)
*/
//设置adapter
.setAdapterPerfect(rvAdapter)
/**
*注意:如果添加了头布局,
*那么ViewHolder内的getPosition()方法返回的是position+1,正确需要getPosition()-1
*getAdapterPosition() 将返回你的adapter内的 position,所以假如调用刷新,需要 *getAdapterPosition()+1
*/
//添加头布局
.addHeaderView(R.layout.header_view)
//添加脚布局
.addFooterView(R.layout.footer_view)
//滚动到脚布局监听
.addScrollBottom(new PerfectRecyclerView.OnScrollBottom() {
@Override
public void scrollBottom() {
//滑动到底部监听
//这里注意:对list进行判断
if (list != null && list.size() > 0) {
//加载数据,然后刷新
(注意:原notifyDataSetChanged()等一系列刷新方法已经改变,下
方有说明)
}
}
});
////////////////////////////////////////////////////////////////////////////////////////
/**
*完整示例
*/
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();
//使用这个header进行findViewById你的布局内的子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);
}
}
}
提供一个稍微简易的adapter,将它复制到你的项目里
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();
}
}
如何使用这个简易adapter
//1.先写一个viewholder
class RvHolder extends RecyclerView.ViewHolder {
private TextView tv;
public RvHolder (View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.tv1);
}
}
//2.使用这个简易的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()
调用这个方法将不会再刷新你的RecyclerView
正确的刷新方法请使用
//全局刷新
mRecyclerView.notifyDataSetChanged();
//某条目刷新
mRecyclerView.notifyItemChanged(int);
//插入某条目
mRecyclerView.notifyItemInserted(int);
//删除某条目
mRecyclerView.notifyItemRemoved(int);
ViewHolder内的getPosition()与getAdapterPosition() 方法使用注意
如果你添加了头布局,
当你需要刷新某一条时候
那么正确的 getPosition() = getPosition()-1
正确的getAdapterPosition() = getAdapterPosition()+1
这里是这个RecyclerView的源码,复制到你的项目里就可以使用了
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;
/**
* 滑动到底部监听
*
* @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);
}
}
}
}