Android筆記(23):使用 Adapter呈現資料清單

Photo by Vivek Chaudhary on Unsplash


根據 Android 官方對 Adapter 的解釋是「Adapter 物件扮演著介於 AdapterView 及 資料之間的橋樑,提供存取資料項目的基本功能」。簡單來說, Adapter 是介於後端資料和前端顯示之間的中介角色,後端常見的有「字串陣列」、「SQLite資料庫」等提供資料的元件,前端常見的 View 有 ListView、GridView 和 Spinner 等,而中介的 Adapter 也有好幾種類型,列於 ListAdapter 的次類別,包含以下四種:
符號說明
ArrayAdapter將陣列的值包裝成清單項目,提供給 Adapter,清單只能顯示一行文字。
SmipleAdapter將 List 集合的值包裝成列表項目。可以自訂各種效果,功能強大。
SmipleCursorAdapter輸入資料是由資料庫(SQLite)查詢的 Cursor(資料庫的游標物件)結果時使用,與 SmipleAdapter 類似,
只不過它需將 Cursor 的欄位與元件ID 對應,直接將資料庫的內容以清單的方式展現出來。
BaseAdapter是一個抽象的類別,繼承它需要較多的客製化(custom),通常它可以對各列表項進行最大限度的定制,
也具有很高的靈活性。

下圖說明 Data、Adapter、View 三者的關係:

[使用Adapter]

Adapter 類別是一個介面,它是元件與資料之間的橋樑,可透過 Adapter 處理資料並將其綁定到對應的元件上。如要建立 ArrayAdapter 物件有兩種方式:一是建立一個字串資源檔(Values Resource File),將列表的項目定義在資源檔中,再透過 XML 佈局檔中使用 <ListView> 標記,使用屬性 android:entries 設定顯示在 ListView 中,這在前一篇 Android筆記(22):UI元件 ListView 列表選單 已經瞭解如何使用;另一種是直接在 java 程式中,以字串陣列的方式儲存列表項目,再以 Adapter 的方式將字串陣列與 ListView 結合。以下就來瞭解一下如何使用 Adapter 將資料 呈現在 ListView 上。可以使用以下兩個個步驟來完成:

(1) 建立 Adapter 物件,如資料來源是文字的清單,通常會使用 ArrayAdapter 物件。
ListView 是 AdatpterView 的次類別,作為資料的容器需要一個能為之處理資料及畫面的 ListAdapter,基本的語法如下:
ListAdapter adapter = new ArrayAdapter<>(this , android.R.layout.simple_list_item_1 ,values);
在建立 Adapter 物件時,可以指定清單的外觀樣式。在 Android 系統中預設提供幾個設定外觀樣式的佈局檔,透過這些佈局檔,可以很方便地指定 ListView 的外觀。常用的佈局檔有以下幾個:
符號說明
simple_list_item_1清單列表是一個普通的文字。
simple_list_item_2清單列表是一個字體較大的文字。
simple_list_item_checked每個清單列表項會有一個選中的列表項目。
simple_list_item_multiple_choice每個清單項都是帶核取方塊的文本。
simple_list_item_single_choice每個清單項都是帶選項按鈕的文本。

這幾個佈局檔產生的結果樣式如下圖:

(2) 建立 Adapter 物件與 ListView 關聯,可以使用 ListView 物件的 setAdapter() 方法來完成,程式碼如下:
listview.setAdapter(adapter);   //將 Adapter 與 ListView 關聯


[程式範例]

(1)新建一個模組 Module,在 res/values 目錄下新增一個字串陣列檔,名為 arrays.xml,定義內容如下:
<resources>
    <string-array name="lv_item">
        <item>香菇湯意麵</item>
        <item>滷肉飯</item>
        <item>餛飩板條</item>
        <item>榨菜肉絲米粉</item>
        <item>香菇湯意麵</item>
        <item>豬肝麵</item>
        <item>高麗菜水餃</item>
    </string-array>
</resources>

(2) 進入 res/layout 目錄下點選佈局檔 activity_main.xml。將預設的內容刪除,建立 1 個 TextView 文字框,1 個 ListView,這裡跟前一篇使用 XML 佈局檔設定不同的地方是少了 android:entries 屬性來設定陣列字串,以下是完整 XML 的內容。
<?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:orientation="vertical">

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="40sp"
        android:layout_marginTop="30sp"
        android:textSize="26sp"
        android:text="午餐要吃什麼?">
    </TextView>

    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</LinearLayout>

(3)在 MainActivity.java 在 onCreate() 方法內,先建立與佈局檔的物件,用 findValueById 連結 ListView 元件,在指定要顯示的字串陣列,接著新增 ArrayAdapter,再使用 setAdapter(adapter) 來進行資料與 ListView 的連結,再設定 setOnItemClickListener 監聽器,如果偵測到選項被按下,執行 onItemClick 程序,使用 getItemAtPosition 方法得知目前按下的值,再將按下該選項的值 Toast 顯示在畫面上。程式碼如下:
package com.example.mylistview;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class lv_MainActivity extends AppCompatActivity {

    private ListView lv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lv_main);

        lv = (ListView) findViewById(R.id.lv);
        String[] values = new String[]{
                "香菇湯意麵", "滷肉飯",  "餛飩板條",  "榨菜肉絲米粉",
                "香菇湯意麵", "豬肝麵",  "高麗菜水餃"};

        ListAdapter adapter = new ArrayAdapter<>(this , android.R.layout.simple_list_item_1 ,values);
        lv.setAdapter(adapter);

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener(){
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                String result = parent.getItemAtPosition(position).toString();
                Toast.makeText(lv_MainActivity.this, result, Toast.LENGTH_LONG).show();
            }
        });
    }
}

執行的結果如下:

[參考資料]


Post a Comment

較新的 較舊