码迷,mamicode.com
首页 > 其他好文 > 详细

BaseAdapter的使用(笔记)

时间:2016-04-13 11:26:10      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:

技术分享


适配器模式的应用:


1.降低程序耦合性

2.容易扩展


BaseAdapter

ListView的显示与缓存机制:需要才显示,显示完就被会受到缓存。

BaseAdapter基本结构

--public int getCount(); 适配器中数据集中数据的个数

--public Object getItem(int position):获取数据集中与指定索引对应的数据项

--public long getItem(int position):获取指定行对应的ID

--public View getView(int position, ViewconverView, ViewGroup parent):获取每一个Item的显示内容


第一步: 创建布局文件 activity_main.xml  创建好了一个简单的listView

创建item布局文件item.xml,其中有一个ImageView 两个 TextView


activity_main.xml 

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ListView
        android:id="@+id/lv_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>



item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    
    <ImageView 
        android:id="@+id/iv_image"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/ic_launcher"/>
    <TextView 
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_toEndOf="@+id/iv_image"
        android:text="Title"
        android:gravity="center"
        android:textSize="25sp"/>
    <TextView 
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_below="@+id/tv_title"
        android:layout_toRightOf="@+id/iv_image"
        android:text="content"
        android:gravity="center_vertical"
        android:textSize="20sp"/>
</RelativeLayout>


效果如图:

技术分享


第二步:创建一个Bean对象ItemBean,封装item中显示的内容,在主页面MainActivity.java里面创建数据源

ItemBean.java

public class ItemBean {

	public int ItemImageResid;
	public String Itemtitle;
	public String ItemContent;
	
	public ItemBean(int itemImageResid, String itemtitle, String itemContent) {
		super();
		ItemImageResid = itemImageResid;
		Itemtitle = itemtitle;
		ItemContent = itemContent;
	}
	
}


MainActivity.java

package com.example.sr;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        List<ItemBean> itemBeanList = new ArrayList<ItemBean>();
        for(int i = 0; i < 20; i++){
        	itemBeanList.add(new ItemBean(R.drawable.ic_launcher, "我是标题"+i, "我是内容"+i));
        }
    }
}


第三步:新建MyAdapter类,继承自BaseAdapter , 重写里面的方法,实现适配器

MyAdapter.java

package com.example.sr;

import java.util.List;

import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public class MyAdapter extends BaseAdapter {

	private List<ItemBean> mList;
	
	public MyAdapter(List<ItemBean> list){  //数据源与适配器进行了关联
		mList = list;
	}
	
	@Override
	public int getCount() { //返回ListView需要显示的数据量
		// TODO Auto-generated method stub
		return mList.size();
	}

	@Override
	public Object getItem(int position) {//获取数据集中与指定索引对应的数据项
		// TODO Auto-generated method stub
		return mList.get(position);
	}

	@Override
	public long getItemId(int position) {//获取指定行对应的ID
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int arg0, View arg1, ViewGroup arg2) {//返回每一项的显示内容
		// TODO Auto-generated method stub
		return null;
	}

}


上面最主要的是getView方法,还没有实现,下面介绍getView方法实现的三重境界

1.逗比式

MyAdapter.java

package com.example.sr;

import java.util.List;

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 MyAdapter extends BaseAdapter {

	private List<ItemBean> mList;
	private LayoutInflater minflater;//布局装载器对象,用于把xml布局文件转化为view
	
	
	public MyAdapter(Context context, List<ItemBean> list){  //数据源与适配器进行了关联
		mList = list;
		minflater = LayoutInflater.from(context);//context要使用当前的Adapter的界面对象
	}
	
	@Override
	public int getCount() { //返回ListView需要显示的数据量
		// TODO Auto-generated method stub
		return mList.size();
	}

	@Override
	public Object getItem(int position) {//获取数据集中与指定索引对应的数据项
		// TODO Auto-generated method stub
		return mList.get(position);
	}

	@Override
	public long getItemId(int position) {//获取指定行对应的ID
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int postion, View convertView, ViewGroup parent) {//返回每一项的显示内容
		// TODO Auto-generated method stub
		View view = minflater.inflate(R.layout.item, null);
		//第一个参数为 需要装载到item.xml布局文件,第二个参数通常写null
		
		ImageView imageView = (ImageView) view.findViewById(R.id.iv_image);
		TextView title = (TextView)view.findViewById(R.id.tv_title);
		TextView content = (TextView)view.findViewById(R.id.tv_content);
		
		//将数据取出来赋给这三个控件
		ItemBean bean = mList.get(postion);
		imageView.setImageResource(bean.ItemImageResid);
		title.setText(bean.Itemtitle);
		content.setText(bean.ItemContent);
		
		return view;
	}

}

回到MainActivity.java   建立listView与MyAdapter的联系

MainActivity.java

package com.example.sr;

import java.util.ArrayList;
import java.util.List;

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

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        List<ItemBean> itemBeanList = new ArrayList<ItemBean>();
        for(int i = 0; i < 20; i++){
        	itemBeanList.add(new ItemBean(R.drawable.ic_launcher, "我是标题"+i, "我是内容"+i));
        }
        
        //建立listView与MyAdapter的联系
        ListView listView = (ListView) findViewById(R.id.lv_main);
        listView.setAdapter(new MyAdapter(this, itemBeanList));//第一个参数为context,第二个是数据源
        
    }
}

至此,运行程序,发现listView可以显示我们想要的东西了。

技术分享


为什么式逗比式呢?listView有缓冲机制,但是在getView无视了缓冲机制,都通过创建一个新的view去设置空间,效率及其低下,完全没有利用到listView的缓存机制。

2. 普通式

修改getView方法

<span style="white-space:pre">	</span>@Override
	public View getView(int postion, View convertView, ViewGroup parent) {//返回每一项的显示内容
		// TODO Auto-generated method stub
		
		//逗比式开始----------
		//View view = minflater.inflate(R.layout.item, null);
		//第一个参数为 需要装载到item.xml布局文件,第二个参数通常写null
		/*
		ImageView imageView = (ImageView) view.findViewById(R.id.iv_image);
		TextView title = (TextView)view.findViewById(R.id.tv_title);
		TextView content = (TextView)view.findViewById(R.id.tv_content);
		
		//将数据取出来赋给这三个控件
		ItemBean bean = mList.get(postion);
		imageView.setImageResource(bean.ItemImageResid);
		title.setText(bean.Itemtitle);
		content.setText(bean.ItemContent);
		*/
		//逗比式结束-----------
		
		//普通式,参数中已经有了一个converView,考虑是否缓存过了,如果缓存过了,可以直接使用
		if(convertView == null){
			convertView = minflater.inflate(R.layout.item, null);
		}
		ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_image);
		TextView title = (TextView)convertView.findViewById(R.id.tv_title);
		TextView content = (TextView)convertView.findViewById(R.id.tv_content);
		ItemBean bean = mList.get(postion);
		imageView.setImageResource(bean.ItemImageResid);
		title.setText(bean.Itemtitle);
		content.setText(bean.ItemContent);
		
		return convertView;
	}

利用了ListView的缓存特性,如果没有缓存才创建新的View,算入门,但是findViewById依然会浪费大量时间

3. 文艺式(最好的)

创建了一个内部类 ViewHolder ,它与view相关联,并缓存item的组件,这样给item设置内容的时候,不用再去findviewById, 直接在ViewHolder里面取出来就行了。

<span style="white-space:pre">	</span>@Override
	public View getView(int postion, View convertView, ViewGroup parent) {//返回每一项的显示内容
		// TODO Auto-generated method stub
		
		//逗比式开始----------
		//View view = minflater.inflate(R.layout.item, null);
		//第一个参数为 需要装载到item.xml布局文件,第二个参数通常写null
		/*
		ImageView imageView = (ImageView) view.findViewById(R.id.iv_image);
		TextView title = (TextView)view.findViewById(R.id.tv_title);
		TextView content = (TextView)view.findViewById(R.id.tv_content);
		
		//将数据取出来赋给这三个控件
		ItemBean bean = mList.get(postion);
		imageView.setImageResource(bean.ItemImageResid);
		title.setText(bean.Itemtitle);
		content.setText(bean.ItemContent);
		*/
		//逗比式结束-----------
		
		
		//普通式,参数中已经有了一个converView,考虑是否缓存过了,如果缓存过了,可以直接使用---------
		/*
		 if(convertView == null){
			convertView = minflater.inflate(R.layout.item, null);
		}
		ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_image);
		TextView title = (TextView)convertView.findViewById(R.id.tv_title);
		TextView content = (TextView)convertView.findViewById(R.id.tv_content);
		ItemBean bean = mList.get(postion);
		imageView.setImageResource(bean.ItemImageResid);
		title.setText(bean.Itemtitle);
		content.setText(bean.ItemContent);
		return convertView;
		*/
		//普通式结束-----------------
		
		ViewHolder viewHolder;
		if(convertView == null){
			viewHolder = new ViewHolder();
			convertView = minflater.inflate(R.layout.item, null);
			viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv_image);//把控件保存在ViewHolder中
			viewHolder.title = (TextView)convertView.findViewById(R.id.tv_title);
			viewHolder.content = (TextView)convertView.findViewById(R.id.tv_content);
			convertView.setTag(viewHolder);//进行关联,把它的控件保存在viewHolder中,避免了findviewbyid去实例化
		}else{
			viewHolder = (ViewHolder)convertView.getTag();
		}
		ItemBean bean = mList.get(postion);
		viewHolder.imageView.setImageResource(bean.ItemImageResid);
		viewHolder.title.setText(bean.Itemtitle);
		viewHolder.content.setText(bean.ItemContent);
		return convertView;
		
	}
	
	class ViewHolder{  //首先创建内部类
		public ImageView imageView;
		public TextView title;
		public TextView content;
	}

不仅利用了ListView的缓存,更通过ViewHolder类来实现显示数据的视图的缓存,避免多次通过findViewById寻找控件,这是最好的方法。

 

总结:

ViewHolder优化BaseAdapter的思路

--创建Bean对象,用于封装数据

--创建MyAdapter(继承BaseAdapter)在构造方法中初始化用于映射的数据List

--创建ViewHolder类,创建布局映射关系

--判断ConverView,为空则创建,并设置Tag,否则通过tag来取出ViewHolder

--给ViewHolder中的控件设置数据


源代码下载:BaseAdapter的使用








BaseAdapter的使用(笔记)

标签:

原文地址:http://blog.csdn.net/sr_19930829/article/details/51140339

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!