網站首頁 編程語言 正文
適配器視圖無處不在,以至于您很難找到一個不使用它們的流行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
相關推薦
- 2022-09-10 Python入門之模塊和包用法詳解_python
- 2022-10-04 C++兩種素數判定方法_C 語言
- 2022-06-08 記一次網站全站http升級為https的過程,websocket : ws升級為wss遇到的問題等
- 2022-09-29 React實現下拉框的key,value的值同時傳送_React
- 2022-10-09 .NET使用Moq進行單元測試_實用技巧
- 2022-11-21 詳解React獲取DOM和獲取組件實例的方式_React
- 2023-03-02 Go語言讀取文本文件的三種方式總結_Golang
- 2022-10-07 Flutter?GetPageRoute實現嵌套導航學習_IOS
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支