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;
        }
  • 相关阅读:
    游标cursor
    SQL: EXISTS
    LeetCode Reverse Integer
    LeetCode Same Tree
    LeetCode Maximum Depth of Binary Tree
    LeetCode 3Sum Closest
    LeetCode Linked List Cycle
    LeetCode Best Time to Buy and Sell Stock II
    LeetCode Balanced Binary Tree
    LeetCode Validate Binary Search Tree
  • 原文地址:https://www.cnblogs.com/guop/p/4981404.html
Copyright © 2011-2022 走看看