BaseAdapter的使用(笔记)


适配器模式的应用:


1.减少程序耦合性

2.easy扩展


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的使用








posted on 2017-08-19 21:44  yjbjingcha  阅读(214)  评论(0编辑  收藏  举报

导航