1. 程式人生 > >RecyclerView使用詳解一代替ListView(點選事件,新增頭佈局,上拉重新整理下拉載入)

RecyclerView使用詳解一代替ListView(點選事件,新增頭佈局,上拉重新整理下拉載入)

老規矩,先看效果;

Recycler是android5.0版本中新新增的一個view;

使用之前必須新增依賴庫:

dependencies {
    compile 'com.android.support:recyclerview-v7:23.0.+'
}

這裡我就不再過多的介紹RecyclerView,既然大家在找使用RecyclerView的demo想必大家都瞭解過了,如果不瞭解網上隨便開啟一篇RecyclerView的文章應該都有,已經爛大街,在此就不過多的重複了;

今天寫的demo主要是利用RecyclerView代替普通的listview和橫向的listview;

個人感覺要想更深入的使用RecyclerView,必須要從最基礎的功能開始實現;今天我們就實現最簡單的五點功能:

功能點:為RecyclerView新增點選事件,新增頭佈局腳佈局,新增下拉重新整理上拉載入更多

好了首先說下如何用RecyclerView代替橫向的listview:

RecyclerView的使用個人感覺其實比較簡單,但是網上很多demo介紹的感覺有點複雜,在本文中RecyclerView的基本使用只需兩步:

第一:設定佈局管理器

第二:設定adapter

        //添加布局管理器,Orientation預設是縱向的,所以我們在此需要手動指定一下
        LinearLayoutManager layoutManager = new LinearLayoutManager(context);
        layoutManager.setOrientation(OrientationHelper.HORIZONTAL);
        recyclerView.setLayoutManager(layoutManager);
        
        //設定recyclerView標記,如果確定內容的高度都一致,設定為true,提高內容渲染效率;(如果高度不確定系統要自己適配高度)
        recyclerView.setHasFixedSize(true);

        //設定adapter
        HRecyclerViewAdapter adapter = new HRecyclerViewAdapter(context, images);
        recyclerView.setAdapter(adapter);

RecyclerVIew提供了三種內建的佈局管理器:

LinearLayoutManager:線性佈局,橫向或者縱向滑動列表

GridLayoutManager:表格佈局

StaggeredGridLayoutManager:流式佈局

我們今天只使用第一種,先了解最實用,最基礎的,後期會更新

RecyclerView預設是沒有分割線的,網上很多demo為了給RecyclerView新增分割線使用了系統提供的類;

個人感覺完全沒必要,甚至感覺多次一舉,個人感覺完全可以給RecyclerView和item設定背景實現分割線或者在item佈局中新增view佈局實現;

首先了解下RecyclerView的adapter:

和listview的adapter有所不同,在這裡需要繼承RecyclerView.Adapter,需要實現三個方法:

onCreateViewHolder()

onBindViewHolder()

getItemCount()

詳情看程式碼:

public class HRecyclerViewAdapter extends RecyclerView.Adapter<HRecyclerViewAdapter.MyViewHolder>{

    private Context context;
    private int[] images;
    private OnItemClickListener onItemClickListener;

    public HRecyclerViewAdapter(Context context, int[] images) {
        this.context=context;
        this.images=images;
    }

    //重寫onCreateViewHolder方法,返回一個自定義的ViewHolder(當RecyclerView需要一個ViewHolder時會回撥該方法,如果有可複用的View不會回撥)
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_hrecycler, parent, false);
        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

  
    //填充onCreateViewHolder方法返回的holder中的控制元件(當一個View需要出現在螢幕上時,該方法會被回撥,我們需要再該方法中根據資料來更改檢視)
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        holder.iv.setBackgroundResource(images[position]);
        if(onItemClickListener!=null){
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int index = holder.getLayoutPosition();
                    //自定義監聽第三步
                    onItemClickListener.onItemClick(index);
                }
            });
        }
    }

    //獲取資料的數量(告訴RecyclerView有多少個檢視需要顯示)
    public int getItemCount() {
        return images.length;
    }

    //自定義的ViewHolder,持有每個Item的的所有介面元素
    public class MyViewHolder extends RecyclerView.ViewHolder{

        public ImageView iv;

        public MyViewHolder(View itemView) {
            super(itemView);
            iv= (ImageView) itemView.findViewById(R.id.imageview);
        }
    }

    //自定義監聽第二步
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener=onItemClickListener;
    }

    //自定義監聽第一步
    public interface OnItemClickListener{
        void onItemClick(int position);
    }

}

從程式碼中大家可以瞭解到RecyclerView的adpater其實只需要實現三個方法,但是我這個adapter中卻多出來幾個方法,RecyclerView本身是沒有條目點選事件的,

所以多出來的幾個方法是變相的給RecyclerView設定設定條目點選事件的,實際上是使用自定義監聽給adapter設定了點選事件;

給RecyclerView設定adapter之後就可以使用了:

adapter.setOnItemClickListener(new HRecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                ToastUtils.showStaticToast(context,"當前點選的是第"+(position+1)+"張圖片");
            }
        });

好了接下來了解下RecyclerView代替縱向listview:

分割線和上面一樣,在item中新增view實現分割線,點選事件同樣是新增自定義監聽;

RecyclerView預設是沒辦法新增頭佈局和腳佈局的,上面橫向的沒有使用這一塊,但是縱向的在真實專案中就極有可能使用到這個功能點了,在網上看了好多大神們寫的新增頭佈局和腳佈局的方法,感覺真的是大神,寫的真的很複雜,所以都沒有使用,最後在git上找到一個自定義的RecyclerView直接繼承系統的RecyclerView,除了添加了兩個方法,其他的用法不變,感覺挺實用的,在此就不復制這個類了,原始碼中都有(MyRecyclerView),使用的話直接複製到專案中即可;

新增頭佈局和腳佈局的方法也極為簡單,和listview一樣:

//新增頭佈局(必須在設定完佈局管理器再新增頭佈局和腳佈局)
        View headerView = View.inflate(this, R.layout.headerview, null);
        myRecyclerView.addHeaderView(headerView);
        //新增腳佈局
        View footView = View.inflate(context, R.layout.footview, null);
        myRecyclerView.addFooterView(footView);
下拉重新整理直接使用的是系統自帶的SwipeRefreshLayout,這個在以前的部落格中也有介紹,在此就不再重複了,不瞭解的朋友可以瞭解一下

直接給RecyclerView新增活動監聽和新增腳佈局實現,首先得到當前頁面顯示的條目個數,adapter一共多少個條目,和當前佈局遮擋頁面個數

先求出用頁面實現個數+被頁面遮擋條目個數的和,然後拿這個和和adapter總條目個數做比較,當等於或者大於adapter條目個數的時候直接載入資料:

 //新增滑動監聽
        myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            //當RecyclerView的滑動狀態改變時觸發
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
           //當RecyclerView滑動時觸發(類似點選事件的MotionEvent.ACTION_MOVE)
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                int visible  = layoutManager.getChildCount();//當天頁面顯示的條目個數
                int total = layoutManager.getItemCount();//當前一共多少個條目
                int past= layoutManager.findFirstCompletelyVisibleItemPosition();//佈局上面被當住多少個條目

                //當活動到最後一個條目時載入更多資料
                if ((visible + past) >= total){
                    <span style="white-space:pre">	</span>//傳送handler載入資料
                        handler.sendEmptyMessageDelayed(1,1000);
                    
                }

            }
        });

好了,以上功能點已經全部實現,如果大家有更簡單的方法實現以上功能點,歡迎告知,感謝;