Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發——RecyclerView特性以及基本使用方法(一)

Android開發——RecyclerView特性以及基本使用方法(一)

編輯:關於Android編程

0. 前言

隨著Android的發展,雖然ListView依舊重要,但RecyclerView確實越來越多的被大家使用。但顯然並不能說RecyclerView就一定優於ListView,而是應該根據不同的需求選擇最合適的進行使用。本篇將介紹我們為什麼要使用RecyclerView,並且它的基本使用方法。

本文原創,轉載請注明出處為SEU_Calvin的博客。

 

1. 我們為什麼要使用RecyclerView

Google聲稱你可以把RecyclerView看成是升級版的ListView,為什麼ListView沒有被遺棄呢?到底RecyclerView強在哪裡了呢?

其實如果你只想簡單的使用滑動顯示這個功能,並且想輕松的使用divider,header,footer或者點擊事件這些功能,那麼使用ListView是完全沒有問題的。RecyclerView除了已經封裝好的Item復用機制外,的重點應該放在靈活性上,高度的解耦,這使得RecyclerView能夠實現深度的定制化,通過提供的不同LayoutManager,ItemDecoration,ItemAnimator等可以實現很多的效果。

(1)RecyclerView提供的三種布局管理器(LayoutManager),可以無縫銜接ListView、GridView,瀑布流的實現也變得簡單,滑動刪除和長按交換只需要添加幾個類就可以實現。

(2)ListView只有一個notifyDatasetChanged方法,想要做局部刷新還是挺麻煩的,但是在RecyclerView中,有很多適配局部刷新的API。

(3)RecyclerView實現Item增刪等動畫效果時,因為有了ItemAnimator因此要比ListView簡單的多。如果想定制Item之間的間隔,使用ItemDecoration也很方便。

(4)關於點擊事件,沒有像ListView那樣現成的API,但是自己封裝起來也不難,而且我們使用ListView時,如果item中有可點擊組件,那麼點擊事件的沖突也是一個問題,而在RecyclerView中則把點擊事件的控制權完全的交給開發者。

 

2. RecyclerView的簡單使用

2.1 Adapter中的實現

 

public class RecyclerAdapter extends RecyclerView.Adapter {
//…
}

 

RecyclerView的Adapter需要繼承RecyclerView.Adapter

其中有幾個比較重要的方法需要實現,分別如下所示:

  @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        if (TYPE_ITEM == viewType) {
            View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
            return new ViewHolder(v);
        } else {
            View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_footer, viewGroup, false);
            return new ViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
           viewHolder.textView.setText(mData.get(i) + i);
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

其中onCreateViewHolder()將布局轉化為View並傳遞給RecyclerView封裝好的ViewHolder,為了展示在RecyclerView中展示兩種布局的方式,做了兩種區分,即如果是RecyclerView的最後一個條目,則換一種布局展示。這裡簡單的設置兩個布局xml只是背景顏色不同,因此可以返回一樣的ViewHolder。而正常情況下可以新建另一個內部類FooterViewHolder extendsRecyclerView.ViewHolder,並在onCreateViewHolder()中進行區分返回。而這個例子中我們返回的ViewHolder是一個內部類。在其中進行控件的初始化。

public class ViewHolder extends RecyclerView.ViewHolder{
        public TextView textView;
        public ViewHolder(View itemView) {
            super(itemView);
            textView = (TextView)itemView.findViewById(R.id.id_num);
        }
}

在onCreateViewHolder(ViewGroup viewGroup, int viewType)中的第二個參數,就是進行類別區分的,和ListView類似,需要在Adapter內部重寫getItemViewType(intposition) 方法,實現哪個位置需要加載哪種布局的邏輯。如下例中,如果是最後一個條目,則返回一個代號。用於onCreateViewHolder()方法中進行具體的布局加載。

 

@Override
public int getItemViewType(int position) {
    if (position + 1 == getItemCount()) {
        return TYPE_FOOTER;
    } else {
        return TYPE_ITEM;
    }
}

 

有了ViewHolder之後,接下來就是要將ViewHolder和數據給綁定到一起來,在必須要實現的第二個方法onBindViewHolder(ViewHolder viewHolder,int i)中則建立起ViewHolder中視圖與數據的關聯。參數一個為對應的ViewHolder,一個為對應的位置。顯然如果需要展示不同的布局,在onBindViewHolder()中通過判斷viewHolder instanceof ViewHolder進行區分,對不同的布局中不同視圖進行不同的數據關聯。

最後getItemCount()是告知RecycleView,此Adapter到底要處理多少個對象。


2.2 Activity中的實現

mRcList = (RecyclerView) findViewById(R.id.rc_list);
mLayoutManager = new LinearLayoutManager(this);
mRcList.setLayoutManager(mLayoutManager);
mRcList.setHasFixedSize(true);
mSpinner = (Spinner) findViewById(R.id.spinner);
        mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView parent, View view, int position, long id) {
                if (position == 0) {
                    mRcList.setLayoutManager(new LinearLayoutManager(MainActivity.this));
                    //設置分隔線
                    mRcList.addItemDecoration(new DividerItemDecoration(MainActivity.this, DividerItemDecoration.VERTICAL));
                } else if (position == 1) {
                    mRcList.setLayoutManager(new GridLayoutManager(MainActivity.this, 3));
                    mRcList.addItemDecoration(new DividerGridItemDecoration(MainActivity.this));
                }else if(position == 2){
                    //代表橫著有10行
                    mRcList.setLayoutManager(new StaggeredGridLayoutManager(10,StaggeredGridLayoutManager.HORIZONTAL));
                    mRcList.addItemDecoration(new DividerGridItemDecoration(MainActivity.this));
                }
            }
            @Override
            public void onNothingSelected(AdapterView parent) {
            }
        });

這裡需要說明的是,現在SDK中提供了三種LayoutManager可以提供給RecyclerView使用,分別為LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager。本例中使用一個Spinner實現一個動態的切換效果。

在設置的分隔線時,LinearLayoutManager設置為了系統默認的分隔線,如12行所示。如果想自定義,則可以在style中加入@drawable/divider,並在divider.xml中自行繪制矩形。而後兩種布局中,默認的分割線是不合適的,DividerGridItemDecoration是自定義的。主要判斷如果是最後一行,則不需要繪制底部;如果是最後一列,則不需要繪制右邊,整個判斷也考慮到了StaggeredGridLayoutManager的橫向和縱向,所以稍稍有些復雜。有興趣的可以在源碼中自行解讀。

mRcList.setHasFixedSize(true)的作用查了一下,解釋如下:

 

//setHasFixedSize() is used to let the RecyclerView keep the same size.
//This information will be used to optimize itself.

 

最後進行數據初始化以及設置Adapter:

for(int i=0; i<=20 ; i++){
    mData.add("Recycler");
}
mAdapter = new RecyclerAdapter(mData);
mRcList.setAdapter(mAdapter);

從效果圖中可以看到,使用RecyclerView實現了兩種不同的布局,通過背景顏色進行區分。而且,可以動態的為RecyclerView設置三種不同的布局。並且當點擊主界面的刪除按鈕時,實現了刪除最後一個Item的操作,這裡notifyDataSetChanged()是通知Adapter數據發生了改變。

public void delRecycler(View view) {
        if (mData.size()> 0) {
            mData.remove(mData.size()- 1);
            mAdapter.notifyDataSetChanged();
        }
}

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved