在阅读此文章前 请先看 http://blog.csdn.net/fangchao3652/article/details/43148871
与开头的连接文章思想类似,只不过那个是图片文字按钮等多种布局的混排,而添加底部只是普通Item 与底部Item两种布局的混排。那个是根据bean中的类型进行判断,然后在onCreateViewholder方法中创建不同的viewholder。而此文章先是根据getItemViewType方法判断item是哪中类型,然后成相应的viewholder.
那么我们就先来看一下getItemViewType方法:
@Override
public int getItemViewType(int position) {
if (position == getContentItemCount() && useFooter()) {
return TYPE_FOOTER;//若是最底下的item加载 footerviewholder
}
return Type_putong;//其他正常的item
}
然后就是onCreateViewHolder了(里面的两个方法等会贴出)
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_FOOTER) {
return onCreateFooterViewHolder(parent, viewType);
}
return onCreateContentItemViewHolder(parent, viewType - TYPE_ADAPTEE_OFFSET);
}
既然创建了不同的viewholder 那绑定的时候也要根据 刚才的返回的viewholder的类型分别绑定:
@Override
public final void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
super.onBindViewHolder(holder,position);
if (position == getContentItemCount() && holder.getItemViewType() == TYPE_FOOTER) {
onBindFooterView(holder, position);//绑定底部item (可见性·赋值。。。)
} else {
onBindContentItemView(holder, position);//绑定普通的item
}
}
//getContentItemCount 是在子类中实现的,获取全部数据的个数
好了主要的就这几个,好了,贴出完整代码:
//用的时候要继承此抽象类,然后实现里面的几个抽象方法即可。
public abstract class FooterAdapter extends BaseAnimAdapter{
private static final int TYPE_FOOTER = Integer.MIN_VALUE;
private static final int TYPE_ADAPTEE_OFFSET = 2;
private boolean canLoadMore = false;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_FOOTER) {
return onCreateFooterViewHolder(parent, viewType);
}
return onCreateContentItemViewHolder(parent, viewType - TYPE_ADAPTEE_OFFSET);
}
@Override
public final void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
super.onBindViewHolder(holder,position);
if (position == getContentItemCount() && holder.getItemViewType() == TYPE_FOOTER) {
onBindFooterView(holder, position);
} else {
onBindContentItemView(holder, position);
}
}
private static class ViewHolderFooter extends RecyclerView.ViewHolder {
public ProgressBar pro;
public TextView title;
public ViewHolderFooter(View v) {
super(v);
pro = (ProgressBar) v.findViewById(R.id.pro);
title = (TextView) v.findViewById(R.id.footerTitle);
}
}
@Override
public int getItemCount() {
int itemCount = getContentItemCount();
if (useFooter()) {
itemCount += 1;
}
return itemCount;
}
@Override
public int getItemViewType(int position) {
if (position == getContentItemCount() && useFooter()) {
return TYPE_FOOTER;
}
return getContentItemType(position) + TYPE_ADAPTEE_OFFSET;
}
public void setCanLoadMore(boolean canLoadMore){
this.canLoadMore = canLoadMore;
}
public boolean isCanLoadMore() {
return canLoadMore;
}
public abstract boolean useFooter();
public RecyclerView.ViewHolder onCreateFooterViewHolder(ViewGroup parent, int viewType){
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.footerview, parent, false);
ViewHolderFooter vh = new ViewHolderFooter(v);
return vh;
}
public void onBindFooterView(RecyclerView.ViewHolder holder, int position){
ViewHolderFooter footerHolder = (ViewHolderFooter) holder;
if (isCanLoadMore()) {
footerHolder.pro.setVisibility(View.VISIBLE);
footerHolder.title.setText("加载更多");
} else {
footerHolder.pro.setVisibility(View.GONE);
footerHolder.title.setText("已到底部");
}
}
public abstract RecyclerView.ViewHolder onCreateContentItemViewHolder(ViewGroup parent, int viewType);//创建你要的普通item
public abstract void onBindContentItemView(RecyclerView.ViewHolder holder, int position);//绑定数据
public abstract int getContentItemCount();
public abstract int getContentItemType(int position);//没用到,返回0即可,为了扩展用的
}
对了,他还有个父类,主要是定义了一个记载时的动画,看一下吧:
public abstract class BaseAnimAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private int lastPosition = -1;
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
setAnimation(holder.itemView, position);
}
private void setAnimation(View viewToAnimate, int position) {
if (position > lastPosition) {
Animation animation = AnimationUtils.loadAnimation(viewToAnimate.getContext(), R.anim.item_slide_bottom_up);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
}
到这布局控件什么的都有了,怎么上拉加载数据呢?我们来个监听器,并暴露一个onloadmore的抽象方法:
public abstract class RecyclerOnScrollListener extends RecyclerView.OnScrollListener {
public static String TAG = RecyclerOnScrollListener.class.getSimpleName();
private LinearLayoutManager manager;
//用来标记是否正在向最后一个滑动,既是否向右滑动或向下滑动
boolean isSlidingToLast = false;
public RecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) {
this.manager = linearLayoutManager;
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
// 当不滚动时
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
//获取最后一个完全显示的ItemPosition
int lastVisibleItem = manager.findLastCompletelyVisibleItemPosition();
int totalItemCount = manager.getItemCount();
// 判断是否滚动到底部,并且是向右滚动
if (lastVisibleItem == (totalItemCount - 1) && isSlidingToLast) {
//加载更多功能的代码
onLoadMore();
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//dx用来判断横向滑动方向,dy用来判断纵向滑动方向
if (dx > 0 || dy > 0) {
//大于0表示,正在向右滚动
isSlidingToLast = true;
} else {
//小于等于0 表示停止或向左滚动
isSlidingToLast = false;
}
}
public abstract void onLoadMore();//要在实现类中实现
}
ok了,最后贴个demo吧:
@EActivity(R.layout.activity_recycler_view)
public class RecyclerViewActivity extends BaseActionBarActivity implements SwipeRefreshLayout.OnRefreshListener {
@ViewById(R.id.swipe_container)
SwipeRefreshLayout mSwipeLayout;
@ViewById(R.id.recycler_view)
RecyclerView mRecyclerView;
private RecyclerViewAdapter mAdapter;
private LinearLayoutManager mLayoutManager;
List<String> myDataset;
@AfterViews
void initView() {
//下拉刷新属性设置
mSwipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
mSwipeLayout.setOnRefreshListener(this);
mSwipeLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
android.R.color.holo_green_light, android.R.color.holo_orange_light,
android.R.color.holo_red_light);
//设置固定大小
// mRecyclerView.setHasFixedSize(true);
/* //设置item动画 mRecyclerView.setItemAnimator(new SlideInOutBottomItemAnimator(mRecyclerView)); mRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL)); */
//设置显示布局方式
mLayoutManager = new LinearLayoutManager(this);
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setOnScrollListener(new RecyclerOnScrollListener(mLayoutManager) {
@Override
public void onLoadMore() {
if(myDataset.size()<50) {
myDataset.add("ccccc");
myDataset.add("ccccc");
myDataset.add("ccccc");
myDataset.add("ccccc");
myDataset.add("ccccc");
myDataset.add("ccccc");
myDataset.add("ccccc");
myDataset.add("ccccc");
mAdapter.setCanLoadMore(true);
}else
mAdapter.setCanLoadMore(false);
mAdapter.notifyDataSetChanged();
}
});
// specify an adapter (see also next example)
myDataset = new ArrayList<>();
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
myDataset.add("aa");
mAdapter = new RecyclerViewAdapter(myDataset);
mAdapter.setCanLoadMore(true);
mRecyclerView.setAdapter(mAdapter);
}
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mSwipeLayout.setRefreshing(false);
// mAdapter.notifyDataSetChanged();
mAdapter.notifyItemInserted(0);
}
}, 2000);
}
}