RecyclerView - 比 ListView 更強大易用效率高的滾動元件
雖然 ListView
可以完成我們大部分列表的需求,不過我們需要使用額外的方式來提高 ListView
的效率,然後 ListView
的擴展性也還不夠全面,它無法做到橫向滾動的效果,所以 Android 提供了一個更強大的元件 — RecyclerView
關於 RecyclerView
可以說是一個加強版的 ListView
,可以實現與 ListView
同樣的效果,也優化了 ListView
中其他不足的地方, Android 官方推薦使用 RecycleView
,也可以實現橫向滾動跟瀑布流佈局。
RecyclerView 基本用法
由於是新增的元件,為了讓Android所有的版本都能使用,將 RecyclerView
定義在了 support
庫當中,所以我們必須先在專案的 build.gradle
中添加相對應的依賴庫才行。
1 2 3 4 5 6 7 8 9 10 11
| dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support:recyclerview-v7:25.3.1' compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12' }
|
我們在 dependencies
區塊中添加 compile 'com.android.support:recyclerview-v7:25.3.1'
,接著修改我們的 activity_main.xml
佈局代碼 :
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView> </LinearLayout>
|
RecyclerView Adapter
接著我們要實現與 ListView
相同的效果,所以我們直接延用之前的圖片及 Fruit 類別以及 layout 檔案,當然 RecyclerView
也跟 ListView
相同,需要一個 Adapter 類別,我們建立一個 FruitApapter
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList; static class ViewHolder extends RecyclerView.ViewHolder { ImageView fruitImage; TextView fruitName;
public ViewHolder(View view) { super(view); fruitImage = (ImageView) view.findViewById(R.id.fruit_image); fruitName = (TextView) view.findViewById(R.id.fruit_name); } }
public FruitAdapter(List<Fruit> fruitList) { mFruitList = fruitList; }
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.fruit_item, parent, false); ViewHolder holder = new ViewHolder(view); return holder; }
@Override public void onBindViewHolder(ViewHolder holder, int position) { Fruit fruit = mFruitList.get(position); holder.fruitImage.setImageResource(fruit.getImageId()); holder.fruitName.setText(fruit.getName()); }
@Override public int getItemCount() { return mFruitList.size(); } }
|
首先,在這個 Adapter
中, 需要定義一個內部類別 ViewHolder
, 它需要繼承 RecyclerView.ViewHolder
。 然後在這個 ViewHolder
的建構子中要傳入一個 View
參數,這個 View
通常都是指向 RecyclerView
子物件中的最外層佈局,接著我們就能用 findViewById()
方法來獲取佈局中的 ImageView
和 TextView
的實體。
FruitAdpater
中也有一個建構子,我們會將需要用到的資料透過建構子注入。由於是繼承 RecyclerView.ViewHolder
,我們必須實作三個 abstract
方法 onCreateViewHolder()
、 onBindViewHolder()
、 getItemCount()
,首先 onCreateViewHolder()
是用來建立 ViewHolder
實體,並把讀取出來的佈局傳入到建構子當中,最後回傳這個實體。 onBindViewHolder()
方法是用於對 RecyclerView
子物件的數據進行賦值,會在子物件出現在可顯示範圍中執行,這裡我們透過 position
參數得到目前的 Fruit
實體,然後再將數據設置到 ViewHolder
的 ImageView
和 TextView
。 getItemCount()
用來告訴 RecyclerView
有多少子元件,直接回傳顯示資料的筆數就可以了。
開始使用 RecyclerView
當我們準備好 Adapter
之後,我們就可以開始使用 RecyclerView
了 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initFruits(); RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view); LinearLayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); FruitAdapter adapter = new FruitAdapter(fruitList); recyclerView.setAdapter(adapter); }
private void initFruits() { for(int i = 0; i < 2; i++) { Fruit apple = new Fruit("蘋果", R.drawable.apple_pic); fruitList.add(apple); Fruit banana = new Fruit("香蕉", R.drawable.banana_pic); fruitList.add(banana); Fruit orange = new Fruit("橘子", R.drawable.orange_pic); fruitList.add(orange); Fruit watermelon = new Fruit("西瓜", R.drawable.watermelon_pic); fruitList.add(watermelon); Fruit pear = new Fruit("梨子", R.drawable.pear_pic); fruitList.add(pear); Fruit grape = new Fruit("葡萄", R.drawable.grape_pic); fruitList.add(grape); Fruit pineapple = new Fruit("鳳梨", R.drawable.pineapple_pic); fruitList.add(pineapple); Fruit strawberry = new Fruit("草莓", R.drawable.strawberry_pic); fruitList.add(strawberry); Fruit cherry = new Fruit("櫻桃", R.drawable.cherry_pic); fruitList.add(cherry); Fruit mango = new Fruit("芒果", R.drawable.mango_pic); fruitList.add(mango);
} } }
|
這邊我們使用跟之前一樣的資料,所以一樣有 initFruits()
方法,接著我們在 onCreate()
方法中我們先拿到 RecyclerView
的實體,接著我們建立一個 LinearLayoutManager
,並設置到 RecyclerView
中,LayoutManager
用於指定 RecyclerView
的佈局方式,這裡使用的 LinearLayoutManager
是線性佈局的意思,接下來建立 FruitAdapter
實體,並且使用 RecyclerView
的 setAdapter
方法完成 Adapter
的設定。這樣就完成了整個 RecyclerView
的實現,並且能做到跟 ListVIew
一模一樣的效果。