zoukankan      html  css  js  c++  java
  • Android ListView使用

    一、ListView的使用

    1、适配器代码

    import java.util.List;
    import cn.com.ista.pdachina.R;
    import cn.com.ista.pdachina.bean.Task;
    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.LinearLayout;
    import android.widget.TextView;
    /*
     * 任务列表数据适配器
     * @author guopeng
     * @created 2015年11月19日
     */
    public class TaskListAdapter extends BaseAdapter {
    
        private Context context;//运行上下文
        private LayoutInflater listContainer;//视图容器,用来导入布局
        private List<自定义类> listitems;//数据集合
        
        static class ViewHolder   
        {  
            private LinearLayout layout;
            private ImageView imageView;
            private TextView taskNumber;
            private TextView taskLocation;
            private TextView taskPostCode;
            private TextView taskCity;
        }
        /*
         * 实例化Adapter
         */
        public TaskListAdapter(Context context, List<Task> listItems)
        {
            this.context = context;
            this.listContainer = LayoutInflater.from(context); //创建视图容器并设置上下文
            this.listitems = listItems;
        }
        
        @Override
        public int getCount() {
            return listitems.size();
        }
    
        @Override
        public Object getItem(int position) {
            return listitems.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            
            Task task = listitems.get(position);
            ViewHolder holder = null;
            
            if(convertView == null)
            {
                holder = new ViewHolder();
                //获取tasklist布局文件的视图
                convertView = listContainer.inflate(R.layout.tasklist_listitem, null);
    
                //获取控件对象
                holder.layout = (LinearLayout) convertView.findViewById(R.id.tasklist_listitem_layout);
                holder.taskNumber = (TextView) convertView.findViewById(R.id.tasklist_listitem_tasknum);
                holder.imageView= (ImageView) convertView.findViewById(R.id.tasklist_listitem_image);
                holder.taskLocation = (TextView) convertView.findViewById(R.id.tasklist_listitem_tasklocation);
                holder.taskPostCode =     (TextView) convertView.findViewById(R.id.tasklist_listitem_taskpostcode);
                holder.taskCity = (TextView) convertView.findViewById(R.id.tasklist_listitem_taskcity);
                
                convertView.setTag(holder);
            }        
            else 
            {
               holder = (ViewHolder) convertView.getTag();
            }
            
            //设置图片和文字
            switch (task.getExecutionState()) 
            {
            case 0:
                holder.layout.setBackgroundResource(R.drawable.tasklist_listitem_undisposed_bg);
                holder.imageView.setBackgroundResource(R.drawable.tasklist_listitem_undisposed_mark);
                break;
            case 1:
                holder.layout.setBackgroundResource(R.drawable.tasklist_listitem_beingprocessed_bg);
                holder.imageView.setBackgroundResource(R.drawable.tasklist_listitem_beingprocessed_mark);
                break;
            case 2:
                holder.layout.setBackgroundResource(R.drawable.tasklist_listitem_completed_bg);
                holder.imageView.setBackgroundResource(R.drawable.tasklist_listitem_completed_mark);
                break;
            case 3:
                holder.layout.setBackgroundResource(R.drawable.tasklist_listitem_canceled_bg);
                holder.imageView.setBackgroundResource(R.drawable.tasklist_listitem_canceled_mark);
                break;
            }
            
            holder.taskNumber.setText(String.valueOf(task.getId()));
            holder.taskLocation.setText(task.getPropertyName()+task.getBuildingName());
            holder.taskPostCode.setText(task.getZipCode());
            holder.taskCity.setText(task.getCity());
            
            return convertView;
        }
    
    }

    ViewHolder重用时候一定要注意先获取ViewHolder对象,然后赋值,不然就可能出现滑动时数据显示错乱问题。

    2、调用

    private void initData()
        {
            List<自定义类> data;final TaskListAdapter adapter = new  TaskListAdapter(appContext, data);
            listView.setAdapter(adapter);
            
            listView.setOnItemClickListener(new OnItemClickListener() {
    
                @Override
                public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                        long arg3) {
                }
            });
        }

    二、Listview性能优化(ViewHolder重用机制)

      ListView优化主要有下面几个方面:

      1、convertView重用

      2、ViewHolder的子View复用

      3、缓存数据复用

    1、convertView重用

    首先讲下ListView的原理:ListView中的每一个Item显示都需要Adapter调用一次getView()的方法,这个方法会传入一个convertView的参数,这个方法返回的View就是这个Item显示的View。如果当Item的数量足够大,再为每一个Item都创建一个View对象,必将占用很多内存空间,即创建View对象(mInflater.inflate(R.layout.lv_item, null);从xml中生成View,这是属于IO操作)是耗时操作,所以必将影响性能。Android提供了一个叫做Recycler(反复循环)的构件,就是当ListView的Item从滚出屏幕视角之外,对应Item的View会被缓存到Recycler中,相应的会从生成一个Item,而此时调用的getView中的convertView参数就是滚出屏幕的缓存Item的View,所以说如果能重用这个convertView,就会大大改善性能。

    那么,我们怎么重用它呢?贴代码:

    @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            
            Task task = listitems.get(position);
            ViewHolder holder = null;
            
            if(convertView == null)
            {
                holder = new ViewHolder();
                //获取tasklist布局文件的视图
                convertView = listContainer.inflate(R.layout.tasklist_listitem, null);
    
    //获取控件对象
                holder.layout = (LinearLayout) convertView.findViewById(R.id.tasklist_listitem_layout);
                holder.taskNumber = (TextView) convertView.findViewById(R.id.tasklist_listitem_tasknum);
                holder.imageView= (ImageView) convertView.findViewById(R.id.tasklist_listitem_image);
                holder.taskLocation = (TextView) convertView.findViewById(R.id.tasklist_listitem_tasklocation);
                holder.taskPostCode =     (TextView) convertView.findViewById(R.id.tasklist_listitem_taskpostcode);
                holder.taskCity = (TextView) convertView.findViewById(R.id.tasklist_listitem_taskcity);
                
                convertView.setTag(holder);
            }        
            else 
            {
               holder = (ViewHolder) convertView.getTag();
            }

    当这个convertView不存在时,即第一次使用它,我们就创建一个item布局的View对象并赋给convertView,以后使用convertView时,只需从convertView中getTag取出来就可以,不需要再次创建item的布局对象了,这样便提高了性能。

    2、使用ViewHolder重用

    我们都知道在getView()方法中的操作是这样的:先从xml中创建view对象(inflate操作,我们采用了重用convertView方法优化),然后在这个view去findViewById,找到每一个item的子View的控件对象,如:ImageView、TextView等。这里的findViewById操作是一个树查找过程,也是一个耗时的操作,所以这里也需要优化,就是使用ViewHolder,把每一个item的子View控件对象都放在Holder中,当第一次创建convertView对象时,便把这些item的子View控件对象findViewById实例化出来并保存到ViewHolder对象中。然后用convertView的setTag将viewHolder对象设置到Tag中, 当以后加载ListView的item时便可以直接从Tag中取出复用ViewHolder对象中的,不需要再findViewById找item的子控件对象了。这样便大大提高了性能。

    贴个完整的代码:

    @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            
            Task task = listitems.get(position);
            ViewHolder holder = null;
            
            if(convertView == null)
            {
                holder = new ViewHolder();
                //获取tasklist布局文件的视图
                convertView = listContainer.inflate(R.layout.tasklist_listitem, null);
    
                //获取控件对象
                holder.layout = (LinearLayout) convertView.findViewById(R.id.tasklist_listitem_layout);
                holder.taskNumber = (TextView) convertView.findViewById(R.id.tasklist_listitem_tasknum);
                holder.imageView= (ImageView) convertView.findViewById(R.id.tasklist_listitem_image);
                holder.taskLocation = (TextView) convertView.findViewById(R.id.tasklist_listitem_tasklocation);
                holder.taskPostCode =     (TextView) convertView.findViewById(R.id.tasklist_listitem_taskpostcode);
                holder.taskCity = (TextView) convertView.findViewById(R.id.tasklist_listitem_taskcity);
                
                convertView.setTag(holder);
            }        
            else 
            {
               holder = (ViewHolder) convertView.getTag();
            }
            
            //设置图片和文字
            switch (task.getExecutionState()) 
            {
            case 0:
                holder.layout.setBackgroundResource(R.drawable.tasklist_listitem_undisposed_bg);
                holder.imageView.setBackgroundResource(R.drawable.tasklist_listitem_undisposed_mark);
                break;
            case 1:
                holder.layout.setBackgroundResource(R.drawable.tasklist_listitem_beingprocessed_bg);
                holder.imageView.setBackgroundResource(R.drawable.tasklist_listitem_beingprocessed_mark);
                break;
            case 2:
                holder.layout.setBackgroundResource(R.drawable.tasklist_listitem_completed_bg);
                holder.imageView.setBackgroundResource(R.drawable.tasklist_listitem_completed_mark);
                break;
            case 3:
                holder.layout.setBackgroundResource(R.drawable.tasklist_listitem_canceled_bg);
                holder.imageView.setBackgroundResource(R.drawable.tasklist_listitem_canceled_mark);
                break;
            }
            
            holder.taskNumber.setText(String.valueOf(task.getId()));
            holder.taskLocation.setText(task.getPropertyName()+task.getBuildingName());
            holder.taskPostCode.setText(task.getZipCode());
            holder.taskCity.setText(task.getCity());
            
            return convertView;
        }
    static class ViewHolder   
        {  
            private LinearLayout layout;
            private ImageView imageView;
            private TextView taskNumber;
            private TextView taskLocation;
            private TextView taskPostCode;
            private TextView taskCity;
        }
  • 相关阅读:
    交叉熵损失函数
    均方根误差(RMSE),平均绝对误差(MAE),标准差(Standard Deviation)
    【转载】【矩阵,数组,列表之间相互转化】
    【数据集介绍】【Point04】
    【视频处理知识】
    【IOU】
    【模型训练】
    【图片操作】
    python 写 XML 文件
    【数组操作】 创建、排序
  • 原文地址:https://www.cnblogs.com/guop/p/4981404.html
Copyright © 2011-2022 走看看