您的位置:首页 > 移动开发 > Android开发

Android之BaseAdapter的使用

2012-07-10 21:46 316 查看
Adapter

Adapter做为这个继承结构的最顶层的基接口,定义了Adapter要实现的基本方法:

public interface Adapter { 
    //注册一个Observer,当Adapter所表示的数据改变时会通知它,DataSetObserver是一个抽象类,定义了两个方法:onChanged与onInvalidated 
    void registerDataSetObserver(DataSetObserver observer); 
    //取消注册一个Observer 
    void unregisterDataSetObserver(DataSetObserver observer); 
    //所表示的数据的项数 
    int getCount(); 
    //返回指定位置的数据项 
    Object getItem(int position); 
    //返回指定位置的数据项的ID 
    long getItemId(int position); 
    //表示所有数据项的ID是否是稳定的,在BaseAdapter中默认返回了false,假设是不稳定的,在CursorAdapter中返回了true,Cursor中的_ID是不变的 
    boolean hasStableIds(); 
    //为每一个数据项产生相应的视图 
    View getView(int position, View convertView, ViewGroup parent); 
    //为了避免产生大量的View浪费内存,在Android中,AdapterView中的View是可回收的使用的。比如你有100项数据要显示,而你的屏幕一次只能显示10条数据,则 
    //只产生10个View,当往下拖动要显示第11个View时,会把第1个View的引用传递过去,更新里面的数据再显示,也就是说View可重用,只是更新视图中的数据用于显示新 
    //的一项,如果一个视图的视图类型是IGNORE_ITEM_VIEW_TYPE的话,则此视图不会被重用 
    static final int IGNORE_ITEM_VIEW_TYPE = AdapterView.ITEM_VIEW_TYPE_IGNORE; 
    //获得相应位置的这图类型 
    int getItemViewType(int position); 
    //getView可以返回的View的类型数量。(在HeaderViewListAdapter中可以包含Header和Footer,getView可以返回Header、Footer及Adapter 
    //中的视图,但其getViewTypeCount的实现只是调用了内部Adapter的的getViewTypeCount,忽略了Header、Footer中的View Type,不懂。 
    int getViewTypeCount(); 
    static final int NO_SELECTION = Integer.MIN_VALUE; 
    boolean isEmpty(); 
}


以前在用到BaseAadpter显示ListView、GridView、Spinner的时候,直接把网上现成的代码拿过来copy一下,然后修修改改就好了,一直也没有详细地总结一下,今天亲自动手写写,发现还是有不少问题的,先上个图看一下这个程序的运行结果:



利用listview在界面上显示,根据不同的位置,显示不同的图片和文字。

第一步:在建立好工程后,首先来看看主类,BaseAdapterDemoActivity

package com.my;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class BaseAdapterDemoActivity extends Activity
{
	private DemoAdapter adapter = null;

	private ListView myListView = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		setView();
	}

	private void setView()
	{
		myListView = (ListView) findViewById(R.id.my_listview);
		adapter = new DemoAdapter(this);
		myListView.setAdapter(adapter);
	}
}
这个BaseAdapterDemoActivity很简单,就是new一个适配器,然后把适配器放到listview当中。第二步:BaseAdapterDemoActivity的布局文件main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/my_linearlayout"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <ListView
    android:id="@+id/my_listview"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    </ListView>
    <!--<GridView
    android:id="@+id/my_gridview"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    </GridView>
    <Spinner
    android:id="@+id/my_spinner"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    </Spinner>
--></LinearLayout>


第三步:为要绘制的每一个条目创建一个布局文件,item_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <ImageView
    android:id="@+id/myimageview"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:src="@drawable/icon"
    >
    </ImageView>
<TextView 
	android:id="@+id/mytext" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/name"
    />
</LinearLayout>


最后一步:也是关键所在,BaseAdapter

package com.my;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class DemoAdapter extends BaseAdapter
{
	private Context c = null;

	private LayoutInflater myInflater = null;

	/**
	 *  构造函数
	 * @param myContext
	 */
	public DemoAdapter(Context myContext)
	{
		c = myContext;
	}

	@Override
	public int getCount()
	{
		// TODO Auto-generated method stub
		return 6;
	}

	@Override
	public Object getItem(int position)
	{
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public long getItemId(int position)
	{
		// TODO Auto-generated method stub
		return position;
	}

	/**
	 * 这个方法getView(),是用来逐一绘制每一条item
	 * 
	 * setTag()会把View与ViewHolder绑定,形成一一对应的关系,拖动listview的时候会重新绘制每一条item
	 * 但是那些已经取得绑定的View,会调用getTag()方法,就不会重新绘制,而是拿到内存中已经取得的资源,提高了效率
	 * 
	 * @param position      position就是位置从0开始
	 * @param convertView   convertView是Spinner,ListView中每一项要显示的view
	 * @param parent        parent就是父窗体了,也就是Spinner,ListView,GridView了
	 * @return              通常return 的view也就是convertView
	 */
	@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		// TODO Auto-generated method stub
		ViewHolder holder = new ViewHolder();
		if (convertView == null)
		{
			/**
			 * 在程序中动态加载以上布局:
			 * LayoutInflater flater = LayoutInflater.from(this);
			 * View view = flater.inflate(R.layout.example, null);
			 */
			myInflater = LayoutInflater.from(c);
			convertView = myInflater.inflate(R.layout.item_list, null);

			holder.icon = (ImageView) convertView
					.findViewById(R.id.myimageview);
			holder.text = (TextView) convertView.findViewById(R.id.mytext);

			convertView.setTag(holder);
		}
		else
		{
			holder = (ViewHolder) convertView.getTag();
		}

		if (position <= 1)
		{
			holder.icon.setImageResource(R.drawable.icon);
			holder.text.setText(R.string.text1);
		}
		else if (position <= 3 && position >= 2)
		{
			holder.icon.setImageResource(R.drawable.icon_b);
			holder.text.setText(R.string.text2);
		}
		else
		{
			holder.icon.setImageResource(R.drawable.icon_c);
			holder.text.setText(R.string.text3);
		}
		return convertView;
	}

	private class ViewHolder
	{
		TextView text;
		ImageView icon;
	}
}


在这段代码中有几点还是需要特别提出来:

1.构造函数public DemoAdapter(Context myContext)可以不用创建,这个创建是因为LayoutInflater需要一个Context;

2.方法public int getCount()是用来说明需要绘制的条目数量,这里是6条;

3.方法public View getView(int position, View convertView, ViewGroup parent)用来逐条绘制,也就是说每绘制一个条目就调用一次这个方法;

4.setTag() getTag()等在代码的注释中加了解释。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: