写在前面
在Android当中,我们常常要使用到ListView,但是ListView有着一定的要求,而数据源却是各种各样的,因此,我们需要利用一个适配器,在适配器当中为ListView填充信息,这样,即降低了ListView的耦合性,也大大提升了其可延展性。
当然在展示对ListView的优化的时候,首先得先建立一个ListView
对ListView的配置
这里主要是大致的展示了我这个ListView的结构
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="75dp"
android:layout_weight="1"
app:srcCompat="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="75dp"
android:layout_weight="4"
android:orientation="vertical">
<TextView
android:id="@+id/list_title"
android:text="title"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<TextView
android:id="@+id/list_message"
android:text="message"
android:textSize="40sp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"/>
</LinearLayout>
</LinearLayout>
大概就是这个样子的
建立对数据源的一种类似映射的关系
public class ListBean {
private String title;
private String message;
private int imageID;
public ListBean(String title, String message, int imageID) {
this.title = title;
this.message = message;
this.imageID = imageID;
}
public String getTitle() {
return title;
}
public String getMessage() {
return message;
}
public int getImageID() {
return imageID;
}
}
然后就是初始化数据源
//建立List
List<ListBean> mList;
//初始化数据
private void initializeData(){
mList = new ArrayList<>();
for(int i = 0;i < 100;i++){
ListBean bean = new ListBean(
"Title: "+ i,
"Message :" + i,
R.mipmap.ic_launcher
);
mList.add(bean);
}
}
对ListView的优化
进行了这么多准备工作之后,终于可以经对ListView的优化了,从本质来说,对ListView的优化就是对Adapter的优化,在这里,首先则是先配置好adapter了
//对Adapter的配置
public class ListAdapter extends BaseAdapter {
//数据源
List<ListBean> mList;
Inflater mInflater;
public ListAdapter(Context context,List<ListBean> listBeen){
this.mList = listBeen;
mInflater = LayoutInflater.from(context);
}
//将数据的大小记录为ListView的大小
@Override
public int getCount() {
return mList.size();
}
//获取相应位置的数据
@Override
public Object getItem(int position) {
return mList.get(position);
}
//获取数据的ID
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
}
在准备完成之后,就可以进行之后的优化了。
首先想让我们看看最初的没有优化过的版本
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//建立视图
View view = mInflater.inflate(R.layout.list_view_layout,null);
//获取ID
TextView title = (TextView) view.findViewById(R.id.list_title);
TextView message =(TextView)view.findViewById(R.id.list_message);
ImageView image = (ImageView) view.findViewById(R.id.imageView);
//建立内容
title.setText(mList.get(position).getTitle());
message.setText(mList.get(position).getMessage());
image.setImageResource(mList.get(position).getImageID());
return view;
}
在这种方法当中,有两个非常耗时的资源,就是,在这里每一个ListView的Item都是一个重新创建的View,而创建View是十分消耗资源的,若一个ListView当中有着成千上万项的话,恐怕没有什么手机能够保存这么多View吧。因此,我们需要利用这里面提供的 convertView来实现View的回收机制
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//若不存在视图的场合,创建一个
if(convertView == null){
convertView = mInflater.inflate(R.layout.list_view_layout,null);
}
//否则利用之前的视图进行操作
TextView title = (TextView) convertView.findViewById(R.id.list_title);
TextView message = (TextView)convertView.findViewById(R.id.list_message);
ImageView image = (ImageView) convertView.findViewById(R.id.imageView);
title.setText(mList.get(position).getTitle());
message.setText(mList.get(position).getMessage());
image.setImageResource(mList.get(position).getImageID());
return convertView;
}
在这里,仅仅是添加了短短的一句判空语句,就实现了View的回收利用机制了。这是因为,在手机当中,能够展示的view始终就那几个,没有必要加载没有展示出来的view,而这里面的convertView则恰恰是展示出来的view,因此,我们只要加载展示出来convertView,就可以了。
而在这里,除了创建view是一个消耗大的操作,findViewById也是一个十分好资源的操作,因为,他需要不断的遍历去寻找你所需要的ID因此,将这一步省略则是我们另一个需要优化打的目标,为此,我们引进了ViewHolder来进行对已经注册了的组件进行保存
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null){
viewHolder = new ViewHolder();
//获取视图
convertView = mInflater.inflate(R.layout.list_view_layout,null);
//获取ID
viewHolder.title = (TextView) convertView.findViewById(R.id.list_title);
viewHolder.message = (TextView)convertView.findViewById(R.id.list_message);
viewHolder.image = (ImageView) convertView.findViewById(R.id.imageView);
//保存已经注册了的组件
convertView.setTag(viewHolder);
}else{
//获取这个视图所对应的组件(此时已注册)
viewHolder = (ViewHolder) convertView.getTag();
}
//创建数据
viewHolder.title.setText(mList.get(position).getTitle());
viewHolder.message.setText(mList.get(position).getMessage());
viewHolder.image.setImageResource(mList.get(position).getImageID());
return convertView;
}
private class ViewHolder{
TextView title;
TextView message;
ImageView image;
}
这样,我们对ListView的优化就完成了