一、擴充卡接口Adapter繼承體系
Adapt是一個接口,是聯通多條目控件AdaptView(ViewGroup是其父類,ListView、GridView、SpinnerView是其子類)與資料集的橋梁,主要有兩個功能:1)決定多條目控件AdaptView子視圖(如ListView)有多少項,即資料集有多少項;2)決定每一項如何顯示,即XML視圖布局和屬性,屬性值由資料集提供。繼承體系如下圖:
Adapter定義的抽象函數主要包括:
</pre><pre name="code" class="java"><pre name="code" class="java">//注冊一個observer,如果資料集發生變化(如增加、删除等等)将會執行
void registerDataSetObserver(DataSetObserver observer);
//取消注冊observer
void unregisterDataSetObserver(DataSetObserver observer);
//顯示有多少個資料項,即adaptView有多少個子節點
int getCount();
//傳回資料集中position位置所對應的資料項
Object getItem(int position);
//傳回position位置所對應的Id号,通常即為position
long getItemId(int position);
//核心函數,傳回position資料項所對應的子節點View
View getView(int position, View convertView, ViewGroup parent);
ListAdapter接口和SpinnerAdapter接口
ListAdapter接口和SpinnerAdapter接口繼承自Adapter。ListAdapter接口是ListView控件與資料集之間的橋梁,該接口隻增加了兩個方法:
//表示擴充卡adapter中的資料項items是否可用,如果資料項有變動,表明資料可靠性無法保證。如果傳回值為true,表明items(所對應的view)是可選中、可點選的
public boolean areAllItemsEnabled();
//傳回值為True,如果position多對應的項是可點選的或可選中的。
boolean isEnabled(int position);
spinnerAdapter接口是spinner控件與資料之間的橋梁,該接口增加了一個方法:
//用下拉視窗顯示position所對應的資料項,作用與getview()方法類似
public View getDropDownView(int position, View convertView, ViewGroup parent);
二、擴充卡基類BaseAdapter
擴充卡類繼承體系如下圖:
擴充卡基類BaseAdapter定義如下:
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter
擴充卡基類BaseAdapter有繼承自接口,即ListAdapter, SpinnerAdapter,表明BaseAdapter及其子類能夠很好處理AdapterView的所有子類視圖,如ListView,SpinnerView等等。
基類方法如下:
//實作注冊Observer,監控資料集變化
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
//實作取消注冊Observer
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
//核心函數,通知綁定的observer資料發生變化,因更新相應的View視圖
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
//實作針對下拉菜單的getDropDownView方法,擷取方式等價于getView
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getView(position, convertView, parent);
}
三、繼承BaseAdapter的擴充卡:數組擴充卡ArrayAdapter
檢視API描述可知,ArrayAdapter預設搭建的是TextView視圖與(String)資料集之間的橋梁,即如果ListView+ArrayAdapter+資料集,ListView子視圖隻能是文本TextView,如果希望子視圖能顯示更多布局形式,比如ImageView,則需要重寫getView函數,但通常都是直接繼承BaseAdapter定制個性的顯示視圖,而不是繼承數組擴充卡。
ListView+ArrayAdapter+String[],實際上采用了MVC設計模式,将前端顯示(ListView)與後端資料String[]進行分離,也就是說視圖ListView不直接讀取資料,而是通過ArrayAdapter進行控制,建立視圖與資料的互動,ArrayAdapter相當于MVC中的控制器C,ListView相當于MVC中的視圖V。
ArrayAdapter有6個構造函數,但最後都是調用init()函數,resource指的是XMl資源值,如果textViewResourceId=0,則resource根節點隻能是TextView,用此XML布局AdapterView中的子節點,如果textViewResourceId=R.id.XXX,指textViewResourceId是XML布局中某個TextView節點,用此節點布局AdapterView中的子節點,最後一個是資料集清單。
private void init(Context context, int resource, int textViewResourceId, List<T> objects) {
mContext = context;
mInflater= (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mResource = mDropDownResource = resource;
mObjects = objects;
mFieldId = textViewResourceId;
}
ListView+ArrayAdapter的一個簡單Demo如下:
package com.study.listviewstudy;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listview=(ListView) findViewById(R.id.listview);
ArrayAdapter<String> adapter=new ArrayAdapter<String>(
this,
R.layout.model,
R.id.model,
getResources().getStringArray(R.array.hero));//讀取strings檔案中的數組hero
listview.setAdapter(adapter);
}
}
建立的布局XML:R.layout.model
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 建立一個textView節點 -->
<TextView
android:id="@+id/model"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="50sp" />
</RelativeLayout>
效果圖: