Android中的BaseAdapter的使用极其优化

来源:互联网 发布:网络故障诊断工具作用 编辑:程序博客网 时间:2024/05/19 10:53

要想使用BaseAdapter,必须知道数据适配器,什么是数据适配器?

数据源,ListView,适配器的关系


分析上图:

Data source数据源的来源是多种多样的,而ListView所展示数据的格式是有一定的要求的,那么数据适配器正好建立了

数据源与ListView之间的一种适配关系。将数据源的数据转换成了ListView正好要显示的数据格式,从而将数据的来源与

数据的显示进行了解耦,降低了程序的耦合性,让程序变得更加容易扩展。这就是Android的适配器模式的使用。

ListView的显示与缓存机制

ListView可以用来展示大量的数据。这里我们假如要显示100条数据,但是手机的大小是有限的,它不可能一下子展示所有的数据。
它可能在一屏中展示7条数据,那么它加载数据的时候,不可能一下子全部加载100条数据,只是加载一屏幕显示的数据。那么当
我们滑动屏幕的时候,第一条数据item1会滑出屏幕的显示区域,这时系统会将这样的一个item回收到一个Recycler中(类似于一个View
的缓冲池),而新要显示的item8就会从这个缓冲池中取出这样的一个布局文件,并重新设置好item8要显示的数据,来设置给要显示的位置。

运行效果图:

代码演示:
MainActivity.java
package com.xbmu;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.widget.ListView;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//创建假数据List<ItemBean> itemBeans  = new ArrayList<ItemBean>();for (int i = 0; i < 20; i++) {itemBeans.add(new ItemBean(R.drawable.ic_launcher, "我是菜鸟"+i, "我会努力学习代码"+i));}ListView mListView = (ListView) findViewById(R.id.lv_main);//设置适配器mListView.setAdapter(new MyAdapter(this, itemBeans));}}
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="match_parent"     android:padding="5dp">    <ImageView        android:id="@+id/iv_icon"        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:text="Title"        android:textSize="25sp"        android:gravity="center_vertical"        android:layout_toRightOf="@id/iv_icon" />    <TextView        android:id="@+id/tv_content"        android:layout_width="match_parent"        android:layout_height="30dp"        android:textSize="20sp"        android:text="Content"        android:gravity="center_vertical"        android:layout_toRightOf="@id/iv_icon"        android:layout_below="@id/tv_title" /></RelativeLayout>
ItemBean.java
package com.xbmu;public class ItemBean {public int itemImageResId;public String itemTitle;public String itemContent;public ItemBean(int itemImageResId, String itemTitle, String itemContent) {super();this.itemImageResId = itemImageResId;this.itemTitle = itemTitle;this.itemContent = itemContent;}}
MyAdapter.java
package com.xbmu;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;//通过构造方法,数数据源与数据适配器关联public MyAdapter(Context context , List<ItemBean> list){mList = list;//这里的context要使用当前的Adapter的界面对象,mInflater布局装载器对象mInflater = LayoutInflater.from(context);}//返回ListView需要显示的数据数量@Overridepublic int getCount() {return mList.size();}//获取对应id项对应的item@Overridepublic Object getItem(int position) {return mList.get(position);}//返回指定索引对应的数据项@Overridepublic long getItemId(int position) {return position;}//返回每一项的现实内容@Overridepublic View getView(int position, View convertView, ViewGroup parent) {/** * 方法一(不推荐):没有利用到ListView的缓存机制 * 但是没有任何优化处理,每次都创建新View,设置控件,效率极其低下//由于我们只需要将xml转化为View,并不涉及到具体的布局,所以第二个参数通常设置为nullView view = mInflater.inflate(R.layout.item, null);//实例化控件ImageView iv_icon = (ImageView) view.findViewById(R.id.iv_icon);TextView tv_title  = (TextView) view.findViewById(R.id.tv_title);TextView tv_content  = (TextView) view.findViewById(R.id.tv_content);//取出bean对象ItemBean bean = mList.get(position);//设置控件的数据iv_icon.setImageResource(bean.itemImageResId);tv_title.setText(bean.itemTitle);tv_content.setText(bean.itemContent);return view;*//** * 方法二(不推荐):利用ListView的缓存特性,如果没有缓存才创建新的View * 但是findViewById()依然浪费大量时间if(convertView == null){//作用:避免重复创建大量的convertView//为空,View未被实例化,缓存池中无缓存。convertView = mInflater.inflate(R.layout.item,null);}ImageView iv_icon = (ImageView) convertView.findViewById(R.id.iv_icon);TextView tv_title  = (TextView) convertView.findViewById(R.id.tv_title);TextView tv_content  = (TextView) convertView.findViewById(R.id.tv_content);ItemBean bean = mList.get(position);iv_icon.setImageResource(bean.itemImageResId);tv_title.setText(bean.itemTitle);tv_content.setText(bean.itemContent);return convertView;*///方法三(推荐使用)/** * 不仅利用了ListView的缓存,更通过ViewHolder类来实现显示数据的视图的缓存, * 避免多次通过findViewById寻找控件 */ViewHolder viewHolder;if(convertView == null){//判断convertView是否为空viewHolder = new ViewHolder();convertView = mInflater.inflate(R.layout.item,null);viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv_icon);viewHolder.title  = (TextView) convertView.findViewById(R.id.tv_title);viewHolder.content  = (TextView) convertView.findViewById(R.id.tv_content);convertView.setTag(viewHolder);//通过setTag将ViewHolder与convertView绑定}else{viewHolder = (ViewHolder) convertView.getTag();//getTag取出关联的ViewHolder}ItemBean bean = mList.get(position);viewHolder.imageView.setImageResource(bean.itemImageResId);viewHolder.title.setText(bean.itemTitle);viewHolder.content.setText(bean.itemContent);return convertView;}//创建内部类ViewHolder,用于缓存控件//作用:避免重复的findViewByIdclass ViewHolder{public ImageView imageView;public TextView title;public TextView content;}}
使用ViewHolder优化BaseAdapter总结:
1.创建Bean对象,用于封装数据
2.在构造方法中初始化用于映射的数据List
3.创建ViewHolder类,创建布局映射关系
4.判断convertView,为空则创建,并设置tag,否则通过tag来取出ViewHolder
5.给ViewHolder中的控件设置数据。


0 0
原创粉丝点击