Android——ListView的优化

写在前面

在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的优化就完成了

猜你喜欢

转载自blog.csdn.net/a591243801/article/details/73195771