Android 效能優化系列 — 26 熟悉 Component 的使用方式 — 以 RecyclerView 為例

Evan Chen
Oct 14, 2022

--

Photo by Marianna Lutkova on Unsplash

Android 為了讓我們開發方便,提供了多樣的 Component 方便各種 UI 的需求。這些 Component 在處理一些複雜的 UI 需求會有一些需要注意的效能問題。這一篇我們就以 RecyclerView 為例來介紹效能優化。

RecyclerView 的部分更新

當 RecyclerView 的資料來源有異動時,一般會使用notifyDataSetChanged 來通知資料有異動,RecyclerView 便能更新畫面。但如果只是少部分的資料異動時,RecyclerView 也提供部分更新項目的功能。例如只是新增一筆資料,是不需要將所有資料重新繫結的。RecyclerView 提供了這幾個方法讓你只更新有異動的部分。

//依position 新增項目
adapter.notifyItemInserted(position)
//依position 移除項目
adapter.notifyItemRemoved(position)
//更新position項目
adapter.notifyItemChanged(position)
//更新一個範圍
adapter.notifyItemRangeInserted(start, end)

圖片的處理

載入圖片需要花費較多資源,在多筆資料呈現就需要注意效能問題。在這個系列已多次的提到使用 Glide 載入圖片,提供延遲載入及Cache等功能。不管你的圖片是存放在 App 裡還是從網址請求圖片,都直接使用像 Glide 這樣的圖片載入套件。

讓圖片高度固定

在 RecyclerView 的每一個 Item 中,如果有使用到圖片,儘量讓圖片高度固定。

確認圖片的大小

檔案太大的圖片將影響效能,確認圖片的大小是否經過最佳化。

onBindViewHolder 不要做太多事

onBindViewHolder 應只處理跟這個 Item 的 UI 繫結有關的事,也就是只會傳資料進來繫結,不在這裡處理太多無關的事。例如要設定事件OnClickListener就應該在onCreateViewHolder處理而不是onBindViewHolder

class MainAdapter(private val names:List<String>) :RecyclerView.Adapter<RecyclerView.ViewHolder>(){    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
return ItemViewHolder(view)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val name = names[position]
(holder as ItemViewHolder).setName(name)
}
override fun getItemCount(): Int {
return names.count()
}
}

正確的使用元件

這篇舉了一個比較容易有效能問題的 RecyclerView 來介紹。Android 有許多的 Component 幫助我們方便做出複雜功能的 UI。在 Android 的官方 Guildeline 大多會有詳細的介紹,請在使用前熟悉使用方式,避免錯誤使用造成效能問題。

下一篇:從介面與功能改善效能

--

--