天天看點

進階控件AdapterView(一):Adapte繼承體系及BaseAdapter

一、擴充卡接口Adapter繼承體系

Adapt是一個接口,是聯通多條目控件AdaptView(ViewGroup是其父類,ListView、GridView、SpinnerView是其子類)與資料集的橋梁,主要有兩個功能:1)決定多條目控件AdaptView子視圖(如ListView)有多少項,即資料集有多少項;2)決定每一項如何顯示,即XML視圖布局和屬性,屬性值由資料集提供。繼承體系如下圖:

進階控件AdapterView(一):Adapte繼承體系及BaseAdapter

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

擴充卡類繼承體系如下圖:

進階控件AdapterView(一):Adapte繼承體系及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>
           

效果圖:

進階控件AdapterView(一):Adapte繼承體系及BaseAdapter