`
zhengjj_2009
  • 浏览: 150194 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

android 继承BaseAdapter的子类的基本实现和改进

 
阅读更多

继承BaseAdapter的子类的基本实现和改进

基本过程:新建TopicAdapter,继承BaseAdapter,重写需要重写的方法。

 

第一步:增加一个带多个参数的构造函数和对应的属性,其目的是为了传递适配器使用过程所必需的参数

      为了传递参数方便,增加TopicAdapter的带多个参数的构造函数,这样在Activity使用Adapter的时候方便使用,这里的多参数的构造函数仅仅是为了传递参数而已。

private List<Topic> dataList;
private int listviewItemRId;
private File cacheDir;
private LayoutInflater inflater;

/**
 * 此构造函数是自己添加的,输入参数的值需要有对应的属性来接收
 * (也可以使用setter方法来实现传值,但个人不赞成)
 * @param context 应用上下文,此处是为了通过context得到LayoutInflater实例
 * @param dataList 传递给Adapter的数据List
 * @param listviewItemRId 显示ListView的条目Item的布局文件的RID
 * @param cacheDir 用于缓存数据和图片文件的SD卡文件路径
 */
public TopicAdapter(Context context, List<Topic> dataList, 
	int listviewItemRId, File cacheDir){
	String serverName = Context.LAYOUT_INFLATER_SERVICE;
	this.inflater = (LayoutInflater)context.getSystemService(serverName);
	this.dataList = dataList;
	this.listviewItemRId = listviewItemRId;
	this.cacheDir = cacheDir;
}

 

第二步、重写几个比较简单的方法

@Override
public int getCount() {
	return dataList.size();
}

@Override
public Object getItem(int position) {
	return dataList.get(position);
}

@Override
public long getItemId(int position) {
	return position;
}

 

第三步、重写getView的方法,详见具体实现。

/**
 * 返回待显示(第position条)Item所对应的View
 * @param position: 是待显示item所对应的index
 * @param convertView: 是待显示item所对应的View
 * @param parent: 是待显示item所对应的View的parent
 */
@Override
public View getView(int position, View convertView, ViewGroup parent) {
	ImageView imageView = null;
	TextView textView = null;
	/**convertView先判断是否为空,如果为空则需要重新创建,然后获得imageView和textView组件;
	 * 如果不为空的,则从缓存中获得获得imageView和textView组件;
	 * 最后为imageView和textView准备对应的数据**/
	if(convertView == null){
		convertView = inflater.inflate(listviewItemRId, null);
		imageView = (ImageView) convertView.findViewById(R.id.imageView);
		textView = (TextView) convertView.findViewById(R.id.textView);
		convertView.setTag(new DataWrapper(imageView, textView));
	}else{
		DataWrapper dataWrapper = (DataWrapper) convertView.getTag();
		imageView = dataWrapper.imageView;
		textView = dataWrapper.textView;	
	}
	try {
		Topic topic = dataList.get(position);
   		textView.setText(topic.title);
   		Uri imageURI = TopicService.getImage(topic.imageSrc, cacheDir);
   		imageView.setImageURI(imageURI);
	} catch (Exception e) {
		e.printStackTrace();
	}
	return convertView;
}

private final class DataWrapper{
	public ImageView imageView;
	public TextView textView;
	public DataWrapper(ImageView imageView, TextView textView) {
		this.imageView = imageView;
		this.textView = textView;
	}
}

 以上的两行代码可能存在较为严重的性能问题,即可能出现ANR的错误。

所以第五步、使用多线程来修改。是修改为以下的代码

try {
	Topic topic = dataList.get(position);
	textView.setText(topic.title);
	//Uri imageURI = TopicService.getImage(topic.imageSrc, cacheDir);
	//imageView.setImageURI(imageURI);
	asyncImageLoad(imageView, topic.imageSrc);
} catch (Exception e) {
	e.printStackTrace();
}

新增新的asyncImageLoad()的方法

private void asyncImageLoad(final ImageView imageView, final String path) {
	final Handler handler = new Handler(){
		public void handleMessage(Message msg) {//运行在主线程中
			/**主线程的handleMessage接到回传数据后,更新imageView的数据**/
			Uri uri = (Uri)msg.obj;
			if(uri!=null && imageView!= null)
				imageView.setImageURI(uri);
		}
	};
	
	Runnable runnable = new Runnable() {			
		public void run() {//在子线程中运行
			try {
				Uri uri = TopicService.getImage(path, cacheDir);
				/*通过handler的sendMessage()来回传数据到主线程*/
				handler.sendMessage(handler.obtainMessage(10, uri));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	};
	new Thread(runnable).start();
}

 

 

第六步、使用AsyncTask优化第五步的多线程代码

 

private void asyncImageLoad(ImageView imageView, String path) {
	AsyncImageTask asyncImageTask = new AsyncImageTask(imageView);
	asyncImageTask.execute(path);
	/**通过asyncImageTask.execute(path)调用AsyncImageTask的doInBackground()方法
	 * path是第一个参数,所以在doInBackground()的params[0]的值其实是path  */
}    
private final class AsyncImageTask extends AsyncTask<String, Integer, Uri>{
	private ImageView imageView;
	public AsyncImageTask(ImageView imageView) {
		this.imageView = imageView;
	}
	protected Uri doInBackground(String... params) {//子线程中执行的
		try {
			/**这里接收到execute传入的path的值进行处理,处理结果Uri返回给onPostExecute**/
			return TopicService.getImage(params[0], cacheDir);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	protected void onPostExecute(Uri result) {//运行在主线程
		if(result!=null && imageView!= null)
			imageView.setImageURI(result);
	}	
}

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics