在使用ListView控件的过程中,由于加载条目过多在滑动时可能造成卡顿,这是因为ListView在当前屏幕中显示多少个条目,就会创建多少个对象,在滑动时,滑出屏幕的条目对象会被销毁,新加载到屏幕的条目会创建新的对象,这样在List View快速滑动时就会不断地创建对象-销毁对象-创建对象,并且每一个条目都需要加载一次布局,加载布局时会不断进行findviewbyid()操作初始化控件,而布局XML文件是以树型结构进行加载,每次加载一个条目都需要从根节点进行初始化,这样对内存消耗也比较大,并且浪费时间,如果每个条目都有图片,图片加载的时间比较长,就会造成内存溢出异常,为此就需要对listview进行优化,优化的目的是在滑动时不会重复创建对象,减少内存消耗和屏幕渲染处理,具体步骤如下:
(1)创建静态类
创建一个静态类,将需要加载的控件变量放在该静态类中,保证所有控件只创建一次,不会重复创建对象
(2)复用缓存view对象
在adapter中的getview(int position,View convertView ,ViewGroup parent)方法中,第二个参数convertView代表的就是之前滑出聘雇的条目对象,如果是第一次加载该方法,会创建新的view对象,如果滑动listview对象,滑动出屏幕的view对象会已缓存的形式存在,而convertView就是缓存的view对象,可以复用缓存该对象减少新对象的创建,在加载布局时先判断convertView是否存在,如果convertView==null说明没有缓存的view对象,则使用view.inflate()方法加载布局,进行布局的优化,否则复用缓存的view对象,需要注意的是,通常情况下,getview()方法中最后返回值都是view,但如果复用了convertView,最后的返回值一定要改为convertview,这样才会将布局显示到页面中。
import java.util.List;
import com.yuan.mobilesafe.R;
import com.yuan.mobilesafe.chapter02.entity.ContactInfo;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class ContactAdapter extends BaseAdapter{
private List<ContactInfo> contactInfos;
private Context context;
public ContactAdapter(List<ContactInfo> contactInfos,Context context) {
super();
this.contactInfos = contactInfos;
this.context = context;
}
@Override
public int getCount() {
return contactInfos.size();
}
@Override
public Object getItem(int position) {
return contactInfos.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
convertView = View.inflate(context, R.layout.item_list_contact_select, null);
holder = new ViewHolder();
holder.mNameTV = (TextView) convertView.findViewById(R.id.tv_name);
holder.mPhoneTV = (TextView)convertView.findViewById(R.id.tv_phone);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
holder.mNameTV.setText(contactInfos.get(position).name);
holder.mPhoneTV.setText(contactInfos.get(position).phone);
return convertView;
}
class ViewHolder{
TextView mNameTV;
TextView mPhoneTV;
}
}
/**
* 联系人实体类
* @author aiyuan
*
*/
public class ContactInfo {
public String id;
public String name;
public String phone;
}
item_list_contact_select.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:background="#10000000"
android:orientation="vertical" >
<View
android:id="@+id/view1"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerVertical="true"
android:layout_margin="15dp"
android:background="@drawable/contact_icon" />
<TextView
android:id="@+id/tv_name"
style="@style/textview16sp"
android:layout_alignTop="@+id/view1"
android:layout_toRightOf="@+id/view1"
android:textColor="@color/purple" />
<TextView
android:id="@+id/tv_phone"
style="@style/textview14sp"
android:layout_toRightOf="@+id/view1"
android:layout_below="@+id/tv_name"
android:layout_marginTop="10dp"
android:textColor="@color/purple" />
</RelativeLayout>