日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Android適配器和適配器視圖

作者:程序員小何SS 更新時間: 2022-10-14 編程語言

適配器視圖無處不在,以至于您很難找到一個不使用它們的流行Android應用程序。該名稱可能聽起來不熟悉,但如果您認為您從未見過適配器視圖,則可能是錯誤的。每次看到 Android 應用以列表、網格或堆棧的形式顯示用戶界面元素時,您都會看到一個正在運行的適配器視圖。

顧名思義,適配器視圖是一個對象。這意味著,您可以將其添加到活動中,就像添加任何其他用戶界面小部件一樣。但是,它無法自行顯示任何數據。其內容始終由另一個對象(適配器)確定。在本教程中,我將向您展示如何創建適配器并使用它們來饋送不同類型的適配器視圖。

1、什么是適配器?

適配器是實現接口的類的對象。它充當數據集和適配器視圖之間的鏈接,適配器視圖是擴展抽象類的類的對象。數據集可以是以結構化方式呈現數據的任何內容。數組、對象和對象是常用的數據集。
適配器負責從數據集中檢索數據并基于該數據生成對象。然后,生成的對象用于填充綁定到適配器的任何適配器視圖。
您可以從頭開始創建自己的適配器類,但大多數開發人員選擇使用或擴展 Android SDK 提供的適配器類。

2、適配器視圖如何工作?

適配器視圖可以非常有效地顯示大型數據集。例如,和小部件可以顯示數百萬個項目,而不會出現任何明顯的滯后,同時保持內存和CPU使用率非常低。他們是怎么做到的?不同的適配器視圖遵循不同的策略。但是,這是他們中的大多數人通常做的事情。
它們僅呈現那些已經在屏幕上或即將在屏幕上移動的對象。這樣,適配器視圖消耗的內存可以是恒定的,并且與數據集的大小無關。
它們還允許開發人員最大限度地減少昂貴的布局膨脹操作,并回收已移出屏幕的現有對象。這樣可以降低 CPU 消耗。

3、創建ArrayAdapter

要創建適配器,您需要具備以下條件:

  • 數據集
  • 包含所生成對象的布局的資源文件
    此外,由于該類只能處理字符串,因此需要確保生成的對象的布局至少包含一個小部件。
    第 1 步:創建數據集
    該類可以使用數組和對象作為數據集。現在,讓我們使用數組作為數據集。
String[] cheeses = {
            "Parmesan",
            "Ricotta",
            "Fontina",
            "Mozzarella",
            "Cheddar"
          };

步驟 2:創建資源文件
創建一個新的布局 XML 文件,其根元素為 ,并將其命名為項.xml。將“大文本”微件拖放到其中,并將其屬性的值設置為cheese_name。布局 XML 文件應如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/activity_horizontal_margin">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/cheese_name" />
</LinearLayout>

步驟 3:創建適配器
在活動中,使用類的構造函數創建類的新實例。作為其參數,傳遞資源文件的名稱、的標識符和對數組的引用。適配器現在已準備就緒。

ArrayAdapter<String> cheeseAdapter = 
    new ArrayAdapter<String>(this,
        R.layout.item,
        R.id.cheese_name,
        cheeses
    );

4. 創建列表

要顯示可垂直滾動的項目列表,可以使用微件。要將小部件添加到活動中,可以將其拖放到活動的布局 XML 文件中,也可以使用 Java 代碼中的構造函數創建小組件。

ListView cheeseList = new ListView(this);
setContentView(cheeseList);

若要將其綁定到我們在上一步中創建的適配器,請調用如下所示的方法。

cheeseList.setAdapter(cheeseAdapter);

如果現在運行應用,則應該能夠以列表的形式查看數組的內容。

5. 創建網格

要顯示可垂直滾動的項目二維網格,可以使用微件。兩者都是抽象類的子類,它們有許多相似之處。因此,如果您知道如何使用其中一個,那么您也知道如何使用另一個。

使用類的構造函數創建一個新實例,并將其傳遞給活動的方法。

GridView cheeseGrid = new GridView(this);
setContentView(cheeseGrid);

若要設置網格中的列數,請調用其方法。我將把它做成一個兩列的網格。

cheeseGrid.setNumColumns(2);

通常,您希望使用 、 和 方法來調整列的寬度和之間的間距。請注意,這些方法使用像素作為其單位。setColumnWidth()setVerticalSpacing()setHorizontalSpacing()

cheeseGrid.setColumnWidth(60);
cheeseGrid.setVerticalSpacing(20);
cheeseGrid.setHorizontalSpacing(20);

現在,您可以使用該方法將 綁定到我們之前創建的適配器。

cheeseGrid.setAdapter(cheeseAdapter);`

再次運行應用以查看外觀。

6. 添加事件偵聽器

可以偵聽適配器視圖中項目的單擊和長單擊事件。例如,讓我們將單擊事件偵聽器添加到 GridView

創建實現接口的匿名類的新實例,并將其傳遞給對象的方法。安卓工作室會為接口的方法自動生成一個存根。您會注意到,該方法的參數包含一個整數,用于指定列表項的位置。您可以使用此整數來找出用戶單擊的數據集中的哪個項目。AdapterView.OnItemClickListenersetOnItemClickListener()GridViewonItemClick()

下面的代碼演示如何在每次單擊 中的項時將簡單消息顯示為小吃欄。

cheeseGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView,
                            View view, int position, long rowId) {
 
        // Generate a message based on the position
        String message = "You clicked on " + cheeses[position];
 
        // Use the message to create a Snackbar
        Snackbar.make(adapterView, message, Snackbar.LENGTH_LONG)
                .show(); // Show the Snackbar
    }
});

如果運行應用并單擊網格中的任意項目,屏幕底部將顯示一條消息。請注意,您可以使用相同的代碼來偵聽。

7. 擴展ArrayAdapter

在它生成的對象的布局中只能處理一個小部件。要拓寬它的功能,你必須擴展它。但是,在我們這樣做之前,讓我們創建一個稍微復雜的數據集。

假設我們的數據集包含以下類的對象,而不是字符串:

static class Cheese {
    String name;
    String description;
 
    public Cheese(String name, String description) {
        this.name = name;
        this.description = description;
    }
}

這是我們將使用的數據集:

Cheese[] cheeses = {
        new Cheese("Parmesan", "Hard, granular cheese"),
        new Cheese("Ricotta", "Italian whey cheese"),
        new Cheese("Fontina", "Italian cow's milk cheese"),
        new Cheese("Mozzarella", "Southern Italian buffalo milk cheese"),
        new Cheese("Cheddar", "Firm, cow's milk cheese"),
};

如您所見,該類包含兩個字段和 。要在列表或網格中顯示這兩個字段,項目的布局必須包含兩個微件。

創建一個新的布局 XML 文件并將其命名為custom_item.xml。向其添加“大文本”和“小文本”構件。將第一個小部件的屬性設置為cheese_name將第二個小部件的屬性設置為cheese_description。布局 XML 文件的內容現在應如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/activity_horizontal_margin">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/cheese_name" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Small Text"
        android:id="@+id/cheese_description" />
</LinearLayout>

還必須能夠處理兩個小部件。重新訪問您的活動,創建一個擴展該類的新匿名類,并重寫其方法。確保將數組作為參數傳遞給其構造函數。

ArrayAdapter<Cheese> cheeseAdapter = 
        new ArrayAdapter<Cheese>(this, 0, cheeses) {
            @Override
            public View getView(int position,
                                View convertView,
                                ViewGroup parent) {
 
            }
        };

在方法內部,必須將參數用作數組的索引,并在該索引處獲取項。getView()position

Cheese currentCheese = cheeses[position];

該方法的第二個參數使我們能夠重用對象。如果忽略它,適配器視圖的性能將很差。首次調用該方法時, 是 。必須通過擴充指定列表項布局的資源文件來初始化它。為此,請使用該方法獲取對 的引用并調用其方法。

// Inflate only once
if(convertView == null) {
    convertView = getLayoutInflater()
                    .inflate(R.layout.custom_item, null, false);
}

此時,您可以使用 來獲取對布局內小部件的引用,并調用它們的方法以使用數組中的數據對其進行初始化。

TextView cheeseName = 
    (TextView)convertView.findViewById(R.id.cheese_name);
TextView cheeseDescription = 
    (TextView)convertView.findViewById(R.id.cheese_description);
 
cheeseName.setText(currentCheese.name);
cheeseDescription.setText(currentCheese.description);

最后,返回,以便它可用于填充與適配器關聯的任何適配器視圖。

return convertView;

8. 使用視圖支架

適配器視圖重復調用該方法以填充自身。因此,您必須嘗試盡量減少在其中執行的操作數。getView()

在上一步中,您可能已經注意到,即使我們確保列表項的布局只膨脹一次,每次調用該方法時都會調用該方法,該方法會消耗許多 CPU 周期。

為了避免這種情況并提高適配器視圖的性能,我們需要將方法的結果存儲在對象中。為此,我們可以使用視圖持有者對象,它只不過是一個類的對象,可以存儲布局中存在的小部件。

由于布局具有兩個構件,因此視圖持有者類還必須具有兩個構件。我已將類命名為“視圖持有者”。

static class ViewHolder{
    TextView cheeseName;
    TextView cheeseDescription;
}

在該方法中,在放大布局后,現在可以使用該方法初始化視圖持有者對象。

ViewHolder viewHolder = new ViewHolder();
viewHolder.cheeseName =
        (TextView)convertView.findViewById(R.id.cheese_name);
viewHolder.cheeseDescription =
        (TextView)convertView.findViewById(R.id.cheese_description);

要將視圖持有者對象存儲在 中,請使用其方法。convertViewsetTag()

// Store results of findViewById
convertView.setTag(viewHolder);

現在,每次調用時,您都可以使用該方法檢索視圖持有者對象,并使用其方法更新其中的小部件。

TextView cheeseName = 
    ((ViewHolder)convertView.getTag()).cheeseName;
TextView cheeseDescription = 
    ((ViewHolder)convertView.getTag()).cheeseDescription;
     
cheeseName.setText(currentCheese.name);
cheeseDescription.setText(currentCheese.description);

如果現在運行應用,則可以看到每個單元格中顯示兩行文本。

原文鏈接:https://blog.csdn.net/xiaokangss/article/details/127287110

欄目分類
最近更新