天天看点

高级控件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