天天看點

RecycleView 添加底部加載更多

在閱讀此文章前 請先看 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();
            }
        }, );
    }


}
           

繼續閱讀