在閱讀此文章前 請先看 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 = ;
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 += ;
}
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 = -;
@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 - ) && isSlidingToLast) {
//加載更多功能的代碼
onLoadMore();
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//dx用來判斷橫向滑動方向,dy用來判斷縱向滑動方向
if (dx > || dy > ) {
//大于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()<) {
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();
}
}, );
}
}