?
Adapter 是將數據綁定到 UI 界面上的橋接類。 Adapter 負責創建顯示每個項目的子 View 和提供對下層數據的訪問。
?
支持 Adapter 綁定的 UI 控件必須擴展 AdapterView 抽象類。創建自己的繼承自 AdapterView 的控件和創建新的 Adapter 類來綁定它們是可能的。
?
一些 Android 提供的 Adapter 介紹
?
在多數情況下,你不需要白手創建自己的 Adapter 。 Android 提供了一系列 Adapter 來將數據綁定到 UI Widget 上。
?
因為 Android 負責提供數據和選擇用于顯示每個項目的 View ,所以 Adapter 能快速地修改要綁定的控件的外觀和功能。下面的列表顯示了兩個最有用和最通用的本地 Adapter :
?
? ArrayAdapter
ArrayAdapter 是一個綁定 View 到一組對象的通用類。默認情況下, ArrayAdapter 綁定每個對象的 toString 值到在 layout 中預先定義的 TextView 控件上。可變通的,構造函數允許你使用更加復雜的 layout 或者通過重寫 getView 方法來擴展類從而使用 TextView 的替代物(如 ImageView 或嵌套的 layout )。
?
? SimpleCursorAdapter
SimpleCursorAdapter 綁定 View 到 Content Provider 查詢返回的游標上。指定一個 XML layout 定義,然后將數據集中的每一列的值綁定到 layout 中的一個 View 上。
?
接下來的章節將深入挖掘這些 Adapter 類的細節。例子中,提供了綁定數據到 ListView 上,盡管這個邏輯會和其他一些 AdapterView 類(如 Spinner 和 Gallery )工作的一樣。
?
使用 Adapter 進行數據綁定
?
將 Adapter 應用到繼承自 AdapterView 類上,你需要調用 View 的 setAdapter 方法,傳入一個 Adapter 實例,如下面的片段所示:
?
ArrayList<String> myStringArray = new ArrayList<String>();
ArrayAdapter<String> myAdapterInstance;
int layoutID = android.R.layout.simple_list_item_1;
myAdapterInstance = new ArrayAdapter<String>(this, layoutID, myStringArray);
myListView.setAdapter(myAdapterInstance);
?
這個片段顯示了最簡單的情況,將數組中的字符串綁定到 ListView 中用于顯示每個項目的簡單 TextView 控件上。
?
接下來的第一個例子顯示了如何綁定一組復雜的對象到 ListView 上,使用一個自定義的 layout 。第二個例子顯示了如何使用 SimpleCursorAdapter 來綁定查詢結果到 ListView 中的自定義 layout 上。
?
?
?
?
在android開發中列表的使用是十分常見的。google對列表的封裝使列表既有顯示傳統文本列表的能力,也有加入了諸如選擇項、復選項等處理事件的能力。這里寫一些我這幾天對這個問題的理解。
在android的api中,LIST和adapter都被放在了android.widget包內。包內的具體結構我這里先不展示了,主要側重列表和adapter。adapter的作用就是將要在列表內顯示的數據和列表本身結合起來。列表本身只完成顯示的作用,其實他就是繼承自VIEWGROUP類。但是他又有一個獨特的函數就是setAdapter()就是完成了view和adapter的結合。adapter如同其本身含義,其實就是一個適配器,他可以對要顯示的數據進行統一的封裝,主要是將數據變成view提供給list。
我們先來看看adapter的體系:
public interface Adapter----0層(表示繼承體系中的層次)
public interface ExpandableListAdapter---(無所謂層次因為沒有其他接口繼承實現它)
這是adapter的始祖,其他個性化的adapter均實現它并加入自己的接口。
public interface ListAdapter----1層
public interface SpinnerAdapter----1層
public interface WrapperListAdapter----2層(實現ListAdapter)
以上接口層面上的體系已經完了。可以看出來作為widget view的橋梁adapter其實只分為2種:ListAdapter和SpinnerAdapter以及ExpandableListAdapter。也就是說所有widget也就是基于list和spinne與ExpandableList三種view形式的。
由于在實際使用時,我們需要將數據加入到Adapter,而以接口形式呈現的adapter無法保存數據,于是Adapter就轉型為類的模式。
public abstract class BaseAdapter----2層(實現了ListAdapter和SpinnerAdapter)
以抽象類的形式出現構造了類型態下的頂層抽象,包容了List和Spinner
public class ArrayAdapter----3層
public class SimpleAdapter---3層
public class CursorAdapter----3層(CursorAdapter其后還有子類這里先不探討)
基本體系有了之后,讓我們看看頂層Adapter里有哪些方法(只列舉常用的):
abstract Object getItem(int position)
abstract int getCount()
abstract long getItemId(int position)
abstract int getItemViewType(int position)
abstract View getView(int position,View convertVeiw,ViewGroup parent)
以上是比較重要的方法,ArrayAdapter他們也是重新實現以上方法的。在實際的開發過程中,往往我們要自己做屬于自己的Adapter,以上方法都是需要重新實現的。
?
?
ArrayAdapter和SimpleCursorAdapter例子
?
使用ArrayAdapter定制 To-Do List
?
這個例子將擴展 To-Do List 工程,以一個 ToDoItem 對象來儲存每一個項目,包含每個項目的創建日期。
?
你將擴展 ArrayAdapter 類來綁定一組 ToDoItem 對象到 ListView 上,并定制用于顯示每一個 ListView 項目的 layout 。
?
1. 返回到 To-Do List 工程。創建一個新的 ToDoItem 類來保存任務和任務的創建日期。重寫 toString 方法來返回一個項目數據的概要。
package com.paad.todolist; import java.text.SimpleDateFormat; import java.util.Date; public class ToDoItem { String task; Date created; public String getTask() { return task; } public Date getCreated() { return created; } public ToDoItem(String _task) { this(_task, new Date(java.lang.System.currentTimeMillis())); } public ToDoItem(String _task, Date _created) { task = _task; created = _created; } @Override public String toString() { SimpleDateFormat sdf = new SimpleDateFormat(“dd/MM/yy”); String dateString = sdf.format(created); return “(“ + dateString + “) “ + task; } }
?
?
?
2. 打開 ToDoList Activity ,修改 ArrayList 和 ArrayAdapter 變量的類型,儲存 ToDoItem 對象而不是字符串。然后,你將修改 onCreate 方法來更新相應的變量初始化。你還需要更新 onKeyListener 處理函數來支持 ToDoItem 對象。
?
?
?
3. 如果你運行 Activity ,它將顯示每個 to-do 項目,如圖 5-3 所示。
?
圖 5-3
?
4. 現在,你可以創建一個自定義的 layout 來顯示每一個 to-do 項目。修改在第 4 章中創建的自定義 layout ,包含另外一個 TextView ,它將用于顯示每個 to-do 項目的創建日期。
<?xml version=”1.0” encoding=”utf-8”?> <RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:background=”@color/notepad_paper”> <TextView android:id=”@+id/rowDate” android:layout_width=”wrap_content” android:layout_height=”fill_parent” android:padding=”10dp” android:scrollbars=”vertical” android:fadingEdge=”vertical” android:textColor=”@color/notepad_text” android:layout_alignParentRight=”true” /> <TextView android:id=”@+id/row” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:padding=”10dp” android:scrollbars=”vertical” android:fadingEdge=”vertical” android:textColor=”@color/notepad_text” android:layout_alignParentLeft=”@+id/rowDate” /> </RelativeLayout>??
5. 創建一個新的類( ToDoItemAdapter ),使用指定的 ToDoItem 變量來擴展一個 ArrayAdapter 。重寫 getView 方法來將 ToDoItem 對象中的 task 和 date 屬性指定給第 4 步創建的 layout 中的 View 。
?
?import java.text.SimpleDateFormat; import android.content.Context; import java.util.*; import android.view.*; import android.widget.*; public class ToDoItemAdapter extends ArrayAdapter<ToDoItem> { int resource; public ToDoItemAdapter(Context _context,int _resource, List<ToDoItem> _items) { super(_context, _resource, _items); resource = _resource; } @Override public View getView(int position, View convertView, ViewGroup parent) { LinearLayout todoView; ToDoItem item = getItem(position); String taskString = item.getTask(); Date createdDate = item.getCreated(); SimpleDateFormat sdf = new SimpleDateFormat(“dd/MM/yy”); String dateString = sdf.format(createdDate); if (convertView == null) { todoView = new LinearLayout(getContext()); String inflater = Context.LAYOUT_INFLATER_SERVICE; LayoutInflater vi; vi = (LayoutInflater)getContext().getSystemService(inflater); vi.inflate(resource, todoView, true); } else { todoView = (LinearLayout) convertView; } TextView dateView = (TextView)todoView.findViewById (R.id.rowDate); TextView taskView = (TextView)todoView.findViewById(R.id.row); dateView.setText(dateString); taskView.setText(taskString); return todoView; } } ?6. 最后,用 ToDoItemAdapter 替換 ArrayAdapter 的定義。
?
private ToDoItemAdapter aa;
?
在 onCreate 中,使用 new ToDoItemAdapter 來替換 ArrayAdapter<String> 的實例化。
?
aa = new ToDoItemAdapter(this, resID, todoItems);
?
7. 如果你運行 Activity ,它看起來如圖 5-4 的截圖。
?
圖 5-4
?
使用SimpleCursorAdapter
?
SimpleCursorAdapter 允許你綁定一個游標的列到 ListView 上,并使用自定義的 layout 顯示每個項目。
?
SimpleCursorAdapter 的創建,需要傳入當前的上下文、一個 layout 資源,一個游標和兩個數組:一個包含使用的列的名字,另一個(相同大小)數組包含 View 中的資源 ID ,用于顯示相應列的數據值。
?
下面的框架代碼顯示了如何構造一個 SimpleCursorAdapter 來顯示聯系人信息:
? String uriString = “content://contacts/people/”; Cursor myCursor = managedQuery(Uri.parse(uriString), null, null, null, null); String[] fromColumns = new String[] { People.NUMBER, eople.NAME }; int[] toLayoutIDs = new int[] { R.id.nameTextView, R.id.numberTextView }; SimpleCursorAdapter myAdapter; myAdapter = new SimpleCursorAdapter(this,R.layout.simplecursorlayout,myCursor,fromColumns,toLayoutIDs)
?
?
SimpleCursorAdapter 在本章前面的創建選擇聯系人的例子中使用過。你將在第 6 章學習到更多關于 Content Provider 和 Cursor 的內容,那里你也將找到更多 SimpleCursorAdapter 的例子。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
