天天看點

android recyclerview,使用 RecyclerView 建立動态清單

使用 RecyclerView 建立動态清單

RecyclerView 可以讓您輕松高效地顯示大量資料。您提供資料并定義每個清單項的外觀,而 RecyclerView 庫會根據需要動态建立元素。

顧名思義,RecyclerView 會回收這些單個的元素。當清單項滾動出螢幕時,RecyclerView 不會銷毀其視圖。相反,RecyclerView 會對螢幕上滾動的新清單項重用該視圖。這種重用可以顯著提高性能,改善應用響應能力并降低功耗。

注意:RecyclerView 除了是類的名稱,也是庫的名稱。在本頁中,采用 code font 字型的 RecyclerView 始終表示 RecyclerView 庫中的類。

關鍵類

将多個不同的類搭配使用,可建構動态清單。

ViewGroup。它本身就是視圖,是以,将 RecyclerView 添加到布局中的方式與添加任何其他界面元素相同。

清單中的每個獨立元素都由一個 ViewHolder 對象進行定義。建立 ViewHolder 時,它并沒有任何關聯的資料。建立 ViewHolder 後,RecyclerView 會将其綁定到其資料。您可以通過擴充 RecyclerView.ViewHolder 來定義 ViewHolder。

RecyclerView 會請求這些視圖,并通過在 Adapter 中調用方法,将視圖綁定到其資料。您可以通過擴充 RecyclerView.Adapter 來定義 Adapter。

布局管理器負責排列清單中的各個元素。您可以使用 RecyclerView 庫提供的某個布局管理器,也可以定義自己的布局管理器。布局管理器均基于庫的 LayoutManager 抽象類。

實作 RecyclerView 的步驟

如果您打算使用 RecyclerView,那麼您需要完成幾項工作。下面幾部分對這些工作進行了詳細介紹。

首先,确定清單或網格的外觀。一般來說,您可以使用 RecyclerView 庫的某個标準布局管理器。

設計清單中每個元素的外觀和行為。根據此設計,擴充 ViewHolder 類。您的 ViewHolder 版本提供了清單項的所有功能。您的 ViewHolder 是 View 的封裝容器,且該視圖由 RecyclerView 管理。

定義用于将您的資料與 ViewHolder 視圖相關聯的 Adapter。

此外,您還可以使用進階自定義選項根據自己的具體需求定制 RecyclerView。

規劃布局

RecyclerView 中的清單項由 LayoutManager 類負責排列。RecyclerView 庫提供了三種布局管理器,用于處理最常見的布局情況:

GridLayoutManager 将所有項排列在二維網格中:

如果網格垂直排列,GridLayoutManager 會盡量使每行中所有元素的寬度和高度相同,但不同的行可以有不同的高度。

如果網格水準排列,GridLayoutManager 會盡量使每列中所有元素的寬度和高度相同,但不同的列可以有不同的寬度。

StaggeredGridLayoutManager 與 GridLayoutManager 類似,但不要求同一行中的清單項具有相同的高度(垂直網格有此要求)或同一列中的清單項具有相同的寬度(水準網格有此要求)。其結果是,同一行或同一列中的清單項可能會錯落不齊。

您還需要設計各個清單項的布局。在設計 ViewHolder 時,您需要使用此布局,如下一部分所述。

實作 Adapter 和 ViewHolder

确定布局後,您需要實作 Adapter 和 ViewHolder。這兩個類配合使用,共同定義資料的顯示方式。ViewHolder 是包含清單中各清單項的布局的 View 的封裝容器。Adapter 會根據需要建立 ViewHolder 對象,還會為這些視圖設定資料。将視圖與其資料相關聯的過程稱為“綁定”。

定義 Adapter 時,您需要替換三個關鍵方法:

onCreateViewHolder():每當 RecyclerView 需要建立新的 ViewHolder 時,它都會調用此方法。此方法會建立并初始化 ViewHolder 及其關聯的 View,但不會填充視圖的内容,因為 ViewHolder 此時尚未綁定到具體資料。

onBindViewHolder():RecyclerView 調用此方法将 ViewHolder 與資料相關聯。此方法會提取适當的資料,并使用該資料填充 ViewHolder 的布局。例如,如果 RecyclerView 顯示的是一個名稱清單,該方法可能會在清單中查找适當的名稱,并填充 ViewHolder 的 TextView 微件。

getItemCount():RecyclerView 調用此方法來擷取資料集的大小。例如,在通訊簿應用中,這可能是位址總數。RecyclerView 使用此方法來确定什麼時候沒有更多的清單項可以顯示。

下面是一個典型的簡單 Adapter 示例,該 Adapter 包含一個顯示資料清單的嵌套 ViewHolder。在本例中,RecyclerView 顯示了一個簡單的文本元素清單。系統會向 Adapter 傳遞一個字元串數組,該數組包含了 ViewHolder 元素的文本。

Kotlin

class CustomAdapter(private val dataSet: Array) :

RecyclerView.Adapter() {

class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

val textView: TextView

init {

// Define click listener for the ViewHolder's View.

textView = view.findViewById(R.id.textView)

}

}

// Create new views (invoked by the layout manager)

override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {

// Create a new view, which defines the UI of the list item

val view = LayoutInflater.from(viewGroup.context)

.inflate(R.layout.text_row_item, viewGroup, false)

return ViewHolder(view)

}

// Replace the contents of a view (invoked by the layout manager)

override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

// Get element from your dataset at this position and replace the

// contents of the view with that element

viewHolder.textView.text = dataSet[position]

}

// Return the size of your dataset (invoked by the layout manager)

override fun getItemCount() = dataSet.size

}Java

public class CustomAdapter extends RecyclerView.Adapter {

private String[] localDataSet;

public static class ViewHolder extends RecyclerView.ViewHolder {

private final TextView textView;

public ViewHolder(View view) {

super(view);

// Define click listener for the ViewHolder's View

textView = (TextView) view.findViewById(R.id.textView);

}

public TextView getTextView() {

return textView;

}

}

public CustomAdapter(String[] dataSet) {

localDataSet = dataSet;

}

// Create new views (invoked by the layout manager)

@Override

public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

// Create a new view, which defines the UI of the list item

View view = LayoutInflater.from(viewGroup.getContext())

.inflate(R.layout.text_row_item, viewGroup, false);

return new ViewHolder(view);

}

// Replace the contents of a view (invoked by the layout manager)

@Override

public void onBindViewHolder(ViewHolder viewHolder, final int position) {

// Get element from your dataset at this position and replace the

// contents of the view with that element

viewHolder.getTextView().setText(localDataSet[position]);

}

// Return the size of your dataset (invoked by the layout manager)

@Override

public int getItemCount() {

return localDataSet.length;

}

}

每個視圖項的布局照例在 XML 布局檔案中定義。在本例中,應用包含一個 text_row_item.xml 檔案,如下所示:

android:layout_width="match_parent"

android:layout_height="@dimen/list_item_height"

android:layout_marginLeft="@dimen/margin_medium"

android:layout_marginRight="@dimen/margin_medium"

android:gravity="center_vertical">

android:id="@+id/textView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/element_text"/>

後續步驟

您可能隻需要這樣一個簡單的 RecyclerView 實作。不過,該庫還提供了許多其他方式供您對實作進行自定義。如需了解詳情,請參閱進階 RecyclerView 自定義。

其他資源

如需詳細了解如何在 Android 平台上進行測試,請參閱以下資源。

示例應用

繼續閱讀