如何使用SnapHelper(kotlin)

如何使用SnapHelper(kotlin)

情境

Google 在 API 24 的時候出了一個 SnapHelper 的工具
這有甚麼用呢?
它類似 ViewPager 的操作方式, 但是,最大的不同點是它的輪詢模式會比較不一樣,一般 ViewPager 一頁就一個 View,而 SnapHelper 可以搭配 RecyclerView 來進行調配,可以滑到一半停止呈現。

完整程式碼

你可以到 GitHub 上觀看或者下載完整程式碼。

程式碼說明

可以看到 Google Play 上的例子正是這種效果。


這邊我們會用到一些圖檔,可以透過以下連結下載。

這邊要透過 Glide 幫忙讀取圖片以及 RecyclerView 呈現,因此,要將 Glide 以及 RecyclerView 的 library 加進 Gradle。

implementation 'androidx.recyclerview:recyclerview:1.1.0'  
implementation 'com.github.bumptech.glide:glide:4.10.0'

一開始我們初始化所有的元件。

private fun initView() {  
 val layoutManager = LinearLayoutManager(this)  
 layoutManager.orientation = LinearLayoutManager.HORIZONTAL  
 recycler_view.layoutManager = layoutManager  
 recycler_view.adapter = mAdapter  
 val snapHelper = LinearSnapHelper()  
 snapHelper.attachToRecyclerView(recycler_view)  
}  
  
private fun initData() {  
 val listItem = ArrayList<Int>()  
 listItem.add(R.drawable.p01)  
 listItem.add(R.drawable.p02)  
 listItem.add(R.drawable.p03)  
 listItem.add(R.drawable.p04)  
 listItem.add(R.drawable.p05)  
 listItem.add(R.drawable.p06)  
 listItem.add(R.drawable.p07)  
 mAdapter = MyAdapter(listItem)  
}

由於我們圖片只放入七張,陣列因此宣告了 7 張圖片,所以,這邊的變化可以自行定義,這邊要注意的是我們預期要將圖片以橫向顯示,因此在 RecyclerView 這邊就要設定為橫向。

layoutManager.orientation = LinearLayoutManager.HORIZONTAL

接著透過 initData() 這個方法,將我們要展示的圖片置入 ArrayList 當中再餵進 Adapter,以下程式碼是 Adapter 的實作。

class MyAdapter(private val mData: List<Int>) : RecyclerView.Adapter<ViewHolder>() {  
  
 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {  
  val v = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_item, parent, false)  
  return ViewHolder(v)  
 }  

 override fun onBindViewHolder(holder: ViewHolder, position: Int) {  
  Glide.with(holder.itemView.context).load(mData[position]).into(holder.imageView)  
 }  

 override fun getItemCount(): Int {  
  return mData.size  
 }  
}

上面還會需要用到 ViewHolder,因此我們還要額外宣告一個 ViewHolder。

class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {  
 var imageView: ImageView = v.findViewById(R.id.img)  
}

這邊注意到 onBindViewHolder 是透過 Glide 去幫我做好一些非同步的讀取圖片處理,並且做好縮圖跟 cache 機制,這樣一來,我們只需要專注在 RecyclerView 元件的操作上就好。

我們最終的效果就會長這樣。


這樣就是一個簡單的 SnapHelper 範例了。