網(wǎng)站首頁 編程語言 正文
適配器視圖無處不在,以至于您很難找到一個不使用它們的流行Android應(yīng)用程序。該名稱可能聽起來不熟悉,但如果您認為您從未見過適配器視圖,則可能是錯誤的。每次看到 Android 應(yīng)用以列表、網(wǎng)格或堆棧的形式顯示用戶界面元素時,您都會看到一個正在運行的適配器視圖。
顧名思義,適配器視圖是一個對象。這意味著,您可以將其添加到活動中,就像添加任何其他用戶界面小部件一樣。但是,它無法自行顯示任何數(shù)據(jù)。其內(nèi)容始終由另一個對象(適配器)確定。在本教程中,我將向您展示如何創(chuàng)建適配器并使用它們來饋送不同類型的適配器視圖。
1、什么是適配器?
適配器是實現(xiàn)接口的類的對象。它充當數(shù)據(jù)集和適配器視圖之間的鏈接,適配器視圖是擴展抽象類的類的對象。數(shù)據(jù)集可以是以結(jié)構(gòu)化方式呈現(xiàn)數(shù)據(jù)的任何內(nèi)容。數(shù)組、對象和對象是常用的數(shù)據(jù)集。
適配器負責從數(shù)據(jù)集中檢索數(shù)據(jù)并基于該數(shù)據(jù)生成對象。然后,生成的對象用于填充綁定到適配器的任何適配器視圖。
您可以從頭開始創(chuàng)建自己的適配器類,但大多數(shù)開發(fā)人員選擇使用或擴展 Android SDK 提供的適配器類。
2、適配器視圖如何工作?
適配器視圖可以非常有效地顯示大型數(shù)據(jù)集。例如,和小部件可以顯示數(shù)百萬個項目,而不會出現(xiàn)任何明顯的滯后,同時保持內(nèi)存和CPU使用率非常低。他們是怎么做到的?不同的適配器視圖遵循不同的策略。但是,這是他們中的大多數(shù)人通常做的事情。
它們僅呈現(xiàn)那些已經(jīng)在屏幕上或即將在屏幕上移動的對象。這樣,適配器視圖消耗的內(nèi)存可以是恒定的,并且與數(shù)據(jù)集的大小無關(guān)。
它們還允許開發(fā)人員最大限度地減少昂貴的布局膨脹操作,并回收已移出屏幕的現(xiàn)有對象。這樣可以降低 CPU 消耗。
3、創(chuàng)建ArrayAdapter
要創(chuàng)建適配器,您需要具備以下條件:
- 數(shù)據(jù)集
- 包含所生成對象的布局的資源文件
此外,由于該類只能處理字符串,因此需要確保生成的對象的布局至少包含一個小部件。
第 1 步:創(chuàng)建數(shù)據(jù)集
該類可以使用數(shù)組和對象作為數(shù)據(jù)集。現(xiàn)在,讓我們使用數(shù)組作為數(shù)據(jù)集。
String[] cheeses = {
"Parmesan",
"Ricotta",
"Fontina",
"Mozzarella",
"Cheddar"
};
步驟 2:創(chuàng)建資源文件
創(chuàng)建一個新的布局 XML 文件,其根元素為 ,并將其命名為項.xml。將“大文本”微件拖放到其中,并將其屬性的值設(shè)置為cheese_name。布局 XML 文件應(yīng)如下所示:
<?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:創(chuàng)建適配器
在活動中,使用類的構(gòu)造函數(shù)創(chuàng)建類的新實例。作為其參數(shù),傳遞資源文件的名稱、的標識符和對數(shù)組的引用。適配器現(xiàn)在已準備就緒。
ArrayAdapter<String> cheeseAdapter =
new ArrayAdapter<String>(this,
R.layout.item,
R.id.cheese_name,
cheeses
);
4. 創(chuàng)建列表
要顯示可垂直滾動的項目列表,可以使用微件。要將小部件添加到活動中,可以將其拖放到活動的布局 XML 文件中,也可以使用 Java 代碼中的構(gòu)造函數(shù)創(chuàng)建小組件。
ListView cheeseList = new ListView(this);
setContentView(cheeseList);
若要將其綁定到我們在上一步中創(chuàng)建的適配器,請調(diào)用如下所示的方法。
cheeseList.setAdapter(cheeseAdapter);
如果現(xiàn)在運行應(yīng)用,則應(yīng)該能夠以列表的形式查看數(shù)組的內(nèi)容。
5. 創(chuàng)建網(wǎng)格
要顯示可垂直滾動的項目二維網(wǎng)格,可以使用微件。兩者都是抽象類的子類,它們有許多相似之處。因此,如果您知道如何使用其中一個,那么您也知道如何使用另一個。
使用類的構(gòu)造函數(shù)創(chuàng)建一個新實例,并將其傳遞給活動的方法。
GridView cheeseGrid = new GridView(this);
setContentView(cheeseGrid);
若要設(shè)置網(wǎng)格中的列數(shù),請調(diào)用其方法。我將把它做成一個兩列的網(wǎng)格。
cheeseGrid.setNumColumns(2);
通常,您希望使用 、 和 方法來調(diào)整列的寬度和之間的間距。請注意,這些方法使用像素作為其單位。setColumnWidth()setVerticalSpacing()setHorizontalSpacing()
cheeseGrid.setColumnWidth(60);
cheeseGrid.setVerticalSpacing(20);
cheeseGrid.setHorizontalSpacing(20);
現(xiàn)在,您可以使用該方法將 綁定到我們之前創(chuàng)建的適配器。
cheeseGrid.setAdapter(cheeseAdapter);`
再次運行應(yīng)用以查看外觀。
6. 添加事件偵聽器
可以偵聽適配器視圖中項目的單擊和長單擊事件。例如,讓我們將單擊事件偵聽器添加到 GridView
創(chuàng)建實現(xiàn)接口的匿名類的新實例,并將其傳遞給對象的方法。安卓工作室會為接口的方法自動生成一個存根。您會注意到,該方法的參數(shù)包含一個整數(shù),用于指定列表項的位置。您可以使用此整數(shù)來找出用戶單擊的數(shù)據(jù)集中的哪個項目。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
}
});
如果運行應(yīng)用并單擊網(wǎng)格中的任意項目,屏幕底部將顯示一條消息。請注意,您可以使用相同的代碼來偵聽。
7. 擴展ArrayAdapter
在它生成的對象的布局中只能處理一個小部件。要拓寬它的功能,你必須擴展它。但是,在我們這樣做之前,讓我們創(chuàng)建一個稍微復雜的數(shù)據(jù)集。
假設(shè)我們的數(shù)據(jù)集包含以下類的對象,而不是字符串:
static class Cheese {
String name;
String description;
public Cheese(String name, String description) {
this.name = name;
this.description = description;
}
}
這是我們將使用的數(shù)據(jù)集:
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"),
};
如您所見,該類包含兩個字段和 。要在列表或網(wǎng)格中顯示這兩個字段,項目的布局必須包含兩個微件。
創(chuàng)建一個新的布局 XML 文件并將其命名為custom_item.xml。向其添加“大文本”和“小文本”構(gòu)件。將第一個小部件的屬性設(shè)置為cheese_name將第二個小部件的屬性設(shè)置為cheese_description。布局 XML 文件的內(nèi)容現(xiàn)在應(yīng)如下所示:
<?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>
還必須能夠處理兩個小部件。重新訪問您的活動,創(chuàng)建一個擴展該類的新匿名類,并重寫其方法。確保將數(shù)組作為參數(shù)傳遞給其構(gòu)造函數(shù)。
ArrayAdapter<Cheese> cheeseAdapter =
new ArrayAdapter<Cheese>(this, 0, cheeses) {
@Override
public View getView(int position,
View convertView,
ViewGroup parent) {
}
};
在方法內(nèi)部,必須將參數(shù)用作數(shù)組的索引,并在該索引處獲取項。getView()position
Cheese currentCheese = cheeses[position];
該方法的第二個參數(shù)使我們能夠重用對象。如果忽略它,適配器視圖的性能將很差。首次調(diào)用該方法時, 是 。必須通過擴充指定列表項布局的資源文件來初始化它。為此,請使用該方法獲取對 的引用并調(diào)用其方法。
// Inflate only once
if(convertView == null) {
convertView = getLayoutInflater()
.inflate(R.layout.custom_item, null, false);
}
此時,您可以使用 來獲取對布局內(nèi)小部件的引用,并調(diào)用它們的方法以使用數(shù)組中的數(shù)據(jù)對其進行初始化。
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);
最后,返回,以便它可用于填充與適配器關(guān)聯(lián)的任何適配器視圖。
return convertView;
8. 使用視圖支架
適配器視圖重復調(diào)用該方法以填充自身。因此,您必須嘗試盡量減少在其中執(zhí)行的操作數(shù)。getView()
在上一步中,您可能已經(jīng)注意到,即使我們確保列表項的布局只膨脹一次,每次調(diào)用該方法時都會調(diào)用該方法,該方法會消耗許多 CPU 周期。
為了避免這種情況并提高適配器視圖的性能,我們需要將方法的結(jié)果存儲在對象中。為此,我們可以使用視圖持有者對象,它只不過是一個類的對象,可以存儲布局中存在的小部件。
由于布局具有兩個構(gòu)件,因此視圖持有者類還必須具有兩個構(gòu)件。我已將類命名為“視圖持有者”。
static class ViewHolder{
TextView cheeseName;
TextView cheeseDescription;
}
在該方法中,在放大布局后,現(xiàn)在可以使用該方法初始化視圖持有者對象。
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);
現(xiàn)在,每次調(diào)用時,您都可以使用該方法檢索視圖持有者對象,并使用其方法更新其中的小部件。
TextView cheeseName =
((ViewHolder)convertView.getTag()).cheeseName;
TextView cheeseDescription =
((ViewHolder)convertView.getTag()).cheeseDescription;
cheeseName.setText(currentCheese.name);
cheeseDescription.setText(currentCheese.description);
如果現(xiàn)在運行應(yīng)用,則可以看到每個單元格中顯示兩行文本。
原文鏈接:https://blog.csdn.net/xiaokangss/article/details/127287110
相關(guān)推薦
- 2022-09-01 基于MFC實現(xiàn)單個文檔的文件讀寫_C 語言
- 2022-06-30 Python中隱藏的五種實用技巧分享_python
- 2022-06-01 python中使用正則表達式的方法詳解_python
- 2022-11-13 如何修改npm默認源為淘寶源
- 2022-08-13 Linux新特性之btrfs文件系統(tǒng)
- 2022-12-07 【Chrome】瀏覽器控制臺設(shè)置成中文
- 2022-07-04 反向傳播BP學習算法Gradient?Descent的推導過程_相關(guān)技巧
- 2022-04-12 一篇文章帶你了解python中的typing模塊和類型注解_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支