BaseAdapter——convertView回收机制与动态控件响应

前言:对于listView的BaseAdapter的派生,难度比较大。最难理解的莫过于getView(int position, View convertView, ViewGroup parent)这个函数是如何产生每条记录的,有些博客中利用holderView,有些博客却没有用,种种方法之间有什么异同,今天我们就来揭开这个绘制ITEM机制的面纱。

本篇借助《PullToRefresh使用详解(二)—重写BaseAdapter实现复杂XML下拉刷新》的例子。所以本篇对于代码的讲解就比较粗略,如果有读者对于如何重写BaseAdapter不太熟悉的话,请先移步看看这篇文章,然后再回来这里,相信会有不一样的收获。

一、ConvertView回收机制

工作原理:

1、ListView 针对List中每个item,要求 adapter “给我一个视图” (getView)。
2、一个新的视图被返回并显示

如果我们有上亿个项目要显示怎么办?为每个项目创建一个新视图?NO!这不可能!
实际上Android为你缓存了视图。Android中有个叫做Recycler的构件,下图是他的工作原理:

如果你有10亿个项目(item),其中只有可见的项目存在内存中,其他的在Recycler中。
ListView先请求一个type1视图(getView)然后请求其他可见的项目。convertView在getView中是空(null)的。
当item1滚出屏幕,并且一个新的项目从屏幕低端上来时,ListView再请求一个type1视图。convertView此时不是空值了,它的值是item1。你只需设定新的数据然后返回convertView,不必重新创建一个视图。   以上摘自《ListView中getView的原理+如何在ListView中放置多个item

也就是说:

1、android的listView在初始化的时候,如上面这个列表,整个屏幕只能放下7个item,那么listView在初始化时,就会只创建7个view,对于这些view也就是参数中的convertView。
2、那问题来了,当继续网上滑动,item1消失了,而item8出来了。那系统还是为item8重新创建一个新的convertView吗?另一个问题,item1的convertView去哪了?(销毁回收资源,还是重新利用?)如果你是系统设计者,你会怎么做?大家想想,如果为每个要显示的item都创建新convertView是不是太浪费了,况且对于item1的convertView已经没用了,我们何不把它拿来给item8用。对!系统就是这样做的!这就是convertView的回收机制。就是将那些不再被用的ITEM的convertView重新给即将显示的ITEM使用的机制!

二、例子

先给大家看一下单个ITEM的布局图片,对于具体布局代码,看源码吧。

对于Java源码,我们先看这种方式写的convertView的生成方法。

  1. package com.example.try_pulltorefresh_map;  
  2. /** 
  3.  * 完成了从TXT文本中提取,并向下刷新 
  4.  * blog:http://blog.csdn.net/harvic880925 
  5.  * @author harvic 
  6.  * @date  2014-5-8 
  7.  *  
  8.  */  
  9. import java.io.BufferedReader;  
  10. import java.io.IOException;  
  11. import java.io.InputStream;  
  12. import java.io.InputStreamReader;  
  13. import java.io.UnsupportedEncodingException;  
  14. import java.util.ArrayList;  
  15. import java.util.HashMap;  
  16. import org.json.JSONArray;  
  17.   
  18. import com.handmark.pulltorefresh.library.PullToRefreshBase;  
  19. import com.handmark.pulltorefresh.library.PullToRefreshListView;  
  20. import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;  
  21. import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;  
  22.   
  23. import android.os.Bundle;  
  24. import android.app.ListActivity;  
  25. import android.content.Context;  
  26. import android.graphics.Color;  
  27. import android.text.format.DateUtils;  
  28. import android.view.LayoutInflater;  
  29. import android.view.View;  
  30. import android.view.ViewGroup;  
  31. import android.widget.BaseAdapter;  
  32. import android.widget.ListView;  
  33. import android.widget.TextView;  
  34.   
  35. public class MainActivity extends ListActivity {  
  36.       
  37.     private ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();  
  38.     private PullToRefreshListView mPullRefreshListView;  
  39.     MyAdapter adapter=null;  
  40.   
  41.     @Override  
  42.     protected void onCreate(Bundle savedInstanceState) {  
  43.         super.onCreate(savedInstanceState);  
  44.         setContentView(R.layout.activity_main);  
  45.           
  46.         mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);  
  47.   
  48.         //设定下拉监听函数  
  49.         mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {  
  50.             @Override  
  51.             public void onRefresh(PullToRefreshBase<ListView> refreshView) {  
  52.                 String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),  
  53.                         DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);  
  54.   
  55.                 // Update the LastUpdatedLabel  
  56.                 refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);  
  57.   
  58.                 // Do work to refresh the list here.  
  59.             }  
  60.         });  
  61.   
  62.         mPullRefreshListView.setMode(Mode.PULL_FROM_END);//设置底部下拉刷新模式  
  63.           
  64.         listItem=getData();//获取LIST数据  
  65.         adapter = new MyAdapter(this);  
  66.   
  67.         //设置适配器  
  68.         ListView actualListView = mPullRefreshListView.getRefreshableView();  
  69.         actualListView.setAdapter(adapter);   
  70.           
  71.     }  
  72.       
  73.     private ArrayList<HashMap<String, Object>> getData() {  
  74.         ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();  
  75.         HashMap<String, Object> map = new HashMap<String, Object>();  
  76.         InputStream inputStream;  
  77.         try {  
  78.             inputStream=this.getAssets().open(“my_home_friends.txt”);  
  79.             String json=readTextFile(inputStream);  
  80.             JSONArray array = new JSONArray(json);  
  81.             for (int i = 0; i < array.length(); i++) {  
  82.                 map = new HashMap<String, Object>();  
  83.                 map.put(”name”, array.getJSONObject(i).getString(“name”));  
  84.                 map.put(”info”, array.getJSONObject(i).getString(“info”));  
  85.                 map.put(”img”,array.getJSONObject(i).getString(“photo”));  
  86.                 list.add(map);  
  87.             }  
  88.             return list;      
  89.               
  90.         } catch (Exception e) {  
  91.             // TODO: handle exception  
  92.             e.printStackTrace();  
  93.         }  
  94.           
  95.           
  96.         return list;      
  97.     }  
  98.   
  99.       
  100.       
  101.     public final class ViewHolder{  
  102.         public TextView name;  
  103.         public TextView info;  
  104.           
  105.         public TextView attentntion;  
  106.     }         
  107.       
  108.     public class MyAdapter extends BaseAdapter{  
  109.   
  110.         private LayoutInflater mInflater;  
  111.           
  112.         public MyAdapter(Context context){  
  113.             this.mInflater = LayoutInflater.from(context);  
  114.         }  
  115.         @Override  
  116.         public int getCount() {  
  117.             // TODO Auto-generated method stub  
  118.             return listItem.size();  
  119.         }  
  120.   
  121.         @Override  
  122.         public Object getItem(int arg0) {  
  123.             // TODO Auto-generated method stub  
  124.             return null;  
  125.         }  
  126.   
  127.         @Override  
  128.         public long getItemId(int arg0) {  
  129.             // TODO Auto-generated method stub  
  130.             return 0;  
  131.         }  
  132.           
  133.         @Override  
  134.         public View getView(int position, View convertView, ViewGroup parent) {  
  135.               
  136.             System.out.println(”position:”+position+“   convertView:”+convertView);  
  137.             ViewHolder holder = null;  
  138.                       
  139.             holder=new ViewHolder();          
  140.             convertView = mInflater.inflate(R.layout.item, null);  
  141.             holder.name = (TextView)convertView.findViewById(R.id.name);  
  142.             holder.info = (TextView)convertView.findViewById(R.id.info);  
  143.             holder.attentntion=(TextView)convertView.findViewById(R.id.attention);  
  144.               
  145.               
  146.             holder.name.setText((String)listItem.get(position).get(”name”));  
  147.             holder.info.setText((String)listItem.get(position).get(”info”));  
  148.               
  149.             final TextView attention=holder.attentntion;  
  150.             holder.attentntion.setOnClickListener(new View.OnClickListener() {                
  151.                 @Override  
  152.                 public void onClick(View v) {  
  153.                     // TODO Auto-generated method stub  
  154.                     attention.setTextColor(Color.RED);  
  155.                 }  
  156.             });  
  157.               
  158.             convertView.setTag(holder);       
  159.   
  160.             return convertView;  
  161.         }  
  162.           
  163.     }  
  164.       
  165.       
  166.     工具类  
  167.     /** 
  168.      *  
  169.      * @param inputStream 
  170.      * @return 
  171.      */  
  172.     public String readTextFile(InputStream inputStream) {  
  173.         String readedStr = ”“;  
  174.         BufferedReader br;  
  175.         try {  
  176.             br = new BufferedReader(new InputStreamReader(inputStream, “UTF-8”));  
  177.             String tmp;  
  178.             while ((tmp = br.readLine()) != null) {  
  179.                 readedStr += tmp;  
  180.             }  
  181.             br.close();  
  182.             inputStream.close();  
  183.         } catch (UnsupportedEncodingException e) {  
  184.             e.printStackTrace();  
  185.         } catch (IOException e) {  
  186.             e.printStackTrace();  
  187.         }  
  188.   
  189.         return readedStr;  
  190.     }  
  191.   
  192.   
  193. }  
package com.example.try_pulltorefresh_map;
/**
 * 完成了从TXT文本中提取,并向下刷新
 * blog:http://blog.csdn.net/harvic880925
 * @author harvic
 * @date  2014-5-8
 * 
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;

import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;

import android.os.Bundle;
import android.app.ListActivity;
import android.content.Context;
import android.graphics.Color;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends ListActivity {

    private ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();
    private PullToRefreshListView mPullRefreshListView;
    MyAdapter adapter=null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);

        //设定下拉监听函数
        mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {
            @Override
            public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),
                        DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);

                // Update the LastUpdatedLabel
                refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);

                // Do work to refresh the list here.
            }
        });

        mPullRefreshListView.setMode(Mode.PULL_FROM_END);//设置底部下拉刷新模式

        listItem=getData();//获取LIST数据
        adapter = new MyAdapter(this);

        //设置适配器
        ListView actualListView = mPullRefreshListView.getRefreshableView();
        actualListView.setAdapter(adapter); 

    }

    private ArrayList<HashMap<String, Object>> getData() {
        ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
        HashMap<String, Object> map = new HashMap<String, Object>();
        InputStream inputStream;
        try {
            inputStream=this.getAssets().open("my_home_friends.txt");
            String json=readTextFile(inputStream);
            JSONArray array = new JSONArray(json);
            for (int i = 0; i < array.length(); i++) {
                map = new HashMap<String, Object>();
                map.put("name", array.getJSONObject(i).getString("name"));
                map.put("info", array.getJSONObject(i).getString("info"));
                map.put("img",array.getJSONObject(i).getString("photo"));
                list.add(map);
            }
            return list;    

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }


        return list;    
    }



    public final class ViewHolder{
        public TextView name;
        public TextView info;

        public TextView attentntion;
    }       

    public class MyAdapter extends BaseAdapter{

        private LayoutInflater mInflater;

        public MyAdapter(Context context){
            this.mInflater = LayoutInflater.from(context);
        }
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return listItem.size();
        }

        @Override
        public Object getItem(int arg0) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public long getItemId(int arg0) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            System.out.println("position:"+position+"   convertView:"+convertView);
            ViewHolder holder = null;

            holder=new ViewHolder();        
            convertView = mInflater.inflate(R.layout.item, null);
            holder.name = (TextView)convertView.findViewById(R.id.name);
            holder.info = (TextView)convertView.findViewById(R.id.info);
            holder.attentntion=(TextView)convertView.findViewById(R.id.attention);


            holder.name.setText((String)listItem.get(position).get("name"));
            holder.info.setText((String)listItem.get(position).get("info"));

            final TextView attention=holder.attentntion;
            holder.attentntion.setOnClickListener(new View.OnClickListener() {              
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    attention.setTextColor(Color.RED);
                }
            });

            convertView.setTag(holder);     

            return convertView;
        }

    }


    工具类
    /**
     * 
     * @param inputStream
     * @return
     */
    public String readTextFile(InputStream inputStream) {
        String readedStr = "";
        BufferedReader br;
        try {
            br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            String tmp;
            while ((tmp = br.readLine()) != null) {
                readedStr += tmp;
            }
            br.close();
            inputStream.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return readedStr;
    }


}

以上代码凡是懂如何派生自BaseAdapter的应该都可以看懂,这里就不再多讲,只看核心代码,摘录如下:

  1. @Override  
  2. public View getView(int position, View convertView, ViewGroup parent) {  
  3.       
  4.     System.out.println(”position:”+position+“   convertView:”+convertView);  
  5.     ViewHolder holder = null;  
  6.               
  7.     holder=new ViewHolder();          
  8.     convertView = mInflater.inflate(R.layout.item, null);  
  9.     holder.name = (TextView)convertView.findViewById(R.id.name);  
  10.     holder.info = (TextView)convertView.findViewById(R.id.info);  
  11.     holder.attentntion=(TextView)convertView.findViewById(R.id.attention);  
  12.       
  13.     holder.name.setText((String)listItem.get(position).get(”name”));  
  14.     holder.info.setText((String)listItem.get(position).get(”info”));  
  15.       
  16.     final TextView attention=holder.attentntion;  
  17.     holder.attentntion.setOnClickListener(new View.OnClickListener() {                
  18.         @Override  
  19.         public void onClick(View v) {  
  20.             // TODO Auto-generated method stub  
  21.             attention.setTextColor(Color.RED);  
  22.         }  
  23.     });   
  24.   
  25.     return convertView;  
  26. }  
@Override
public View getView(int position, View convertView, ViewGroup parent) {

    System.out.println("position:"+position+"   convertView:"+convertView);
    ViewHolder holder = null;

    holder=new ViewHolder();        
    convertView = mInflater.inflate(R.layout.item, null);
    holder.name = (TextView)convertView.findViewById(R.id.name);
    holder.info = (TextView)convertView.findViewById(R.id.info);
    holder.attentntion=(TextView)convertView.findViewById(R.id.attention);

    holder.name.setText((String)listItem.get(position).get("name"));
    holder.info.setText((String)listItem.get(position).get("info"));

    final TextView attention=holder.attentntion;
    holder.attentntion.setOnClickListener(new View.OnClickListener() {              
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            attention.setTextColor(Color.RED);
        }
    }); 

    return convertView;
}

这里利用system.out.println对convertView进行捕捉,运行如果如下:

手机初始化是这样子的:

根据上面我们讲的理论,在初始化时,整个屏幕能放下三个ITEM,所以会创建三个全新的convertView。当我往下拉一个ITEM,出现第四个ITEM的时候,就会回收第一个ITEM的convertView给第四个。捕捉结果如下:


清楚的看到,前四个convertView为NULL,当第五个ITEM出现时,此时由于第一个ITEM肯定已经滚出屏幕,所以将其重新传给即将出现的item5使用。我们上面说的第四个ITEM出现的时候就应该不再创建新convertView了,我想android开发者在考虑多创建一个ITEM的目的在于更安全吧。
回到上面的代码,好像看着代码没有任何问题,我在里面写了个clickListener,当点击“关注”的时候,字体会变红,试一下。
            点击“关注”                     下拉后再拉回来

    

问题出现了:当拉回来的时候,“关注”不再红了!!!!!!为什么????
问题出在代码上:

  1. holder=new ViewHolder();          
  2. convertView = mInflater.inflate(R.layout.item, null);  
  3. holder.name = (TextView)convertView.findViewById(R.id.name);  
  4. holder.info = (TextView)convertView.findViewById(R.id.info);  
  5. holder.attentntion=(TextView)convertView.findViewById(R.id.attention);  
holder=new ViewHolder();       
convertView = mInflater.inflate(R.layout.item, null);
holder.name = (TextView)convertView.findViewById(R.id.name);
holder.info = (TextView)convertView.findViewById(R.id.info);
holder.attentntion=(TextView)convertView.findViewById(R.id.attention);

每次运行getView获取当前ITEM时,都会重新new 一个viewHolder与R.layout.item绑定,也就是说,每次都会产生一个新布局赋值给convertView让其显示。而我们上面讲了,android会将回收过来的convertView返回给即将显示的getView使用,以节约资源。而我们这里却没有领情,每次都重新创建一个布局赋给convertView,由于每次都创建一个新布局,所以当ITEM1被重新拉回来显示的时候,由于是重新创建的布局,当然是初始状态。“关注”当然也就是黑色的了。
改进:

  1. @Override  
  2. public View getView(int position, View convertView, ViewGroup parent) {  
  3.       
  4.     System.out.println(”position:”+position+“   convertView:”+convertView);  
  5.     ViewHolder holder = null;  
  6.       
  7.     if (convertView == null) {  
  8.           
  9.     holder=new ViewHolder();      
  10.     convertView = mInflater.inflate(R.layout.item, null);  
  11.     holder.name = (TextView)convertView.findViewById(R.id.name);  
  12.     holder.info = (TextView)convertView.findViewById(R.id.info);  
  13.     holder.attentntion=(TextView)convertView.findViewById(R.id.attention);  
  14.     convertView.setTag(holder);       
  15.     }else {  
  16.       
  17.     holder = (ViewHolder)convertView.getTag();  
  18.     }  
  19.       
  20.     holder.name.setText((String)listItem.get(position).get(”name”));  
  21.     holder.info.setText((String)listItem.get(position).get(”info”));  
  22.       
  23.     final TextView attention=holder.attentntion;  
  24.     holder.attentntion.setOnClickListener(new View.OnClickListener() {                
  25.         @Override  
  26.         public void onClick(View v) {  
  27.             // TODO Auto-generated method stub  
  28.             attention.setTextColor(Color.RED);  
  29.         }  
  30.     });  
  31.     return convertView;  
  32. }     
@Override
public View getView(int position, View convertView, ViewGroup parent) {

    System.out.println("position:"+position+"   convertView:"+convertView);
    ViewHolder holder = null;

    if (convertView == null) {

    holder=new ViewHolder();    
    convertView = mInflater.inflate(R.layout.item, null);
    holder.name = (TextView)convertView.findViewById(R.id.name);
    holder.info = (TextView)convertView.findViewById(R.id.info);
    holder.attentntion=(TextView)convertView.findViewById(R.id.attention);
    convertView.setTag(holder);     
    }else {

    holder = (ViewHolder)convertView.getTag();
    }

    holder.name.setText((String)listItem.get(position).get("name"));
    holder.info.setText((String)listItem.get(position).get("info"));

    final TextView attention=holder.attentntion;
    holder.attentntion.setOnClickListener(new View.OnClickListener() {              
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            attention.setTextColor(Color.RED);
        }
    });
    return convertView;
}   

不同的部分在这:

  1. ViewHolder holder = null;  
  2.   
  3. if (convertView == null) {  
  4.       
  5. holder=new ViewHolder();      
  6. convertView = mInflater.inflate(R.layout.item, null);  
  7. holder.name = (TextView)convertView.findViewById(R.id.name);  
  8. holder.info = (TextView)convertView.findViewById(R.id.info);  
  9. holder.attentntion=(TextView)convertView.findViewById(R.id.attention);  
  10. convertView.setTag(holder);       
  11. }else {  
  12.   
  13. holder = (ViewHolder)convertView.getTag();  
  14. }  
ViewHolder holder = null;

if (convertView == null) {

holder=new ViewHolder();    
convertView = mInflater.inflate(R.layout.item, null);
holder.name = (TextView)convertView.findViewById(R.id.name);
holder.info = (TextView)convertView.findViewById(R.id.info);
holder.attentntion=(TextView)convertView.findViewById(R.id.attention);
convertView.setTag(holder);     
}else {

holder = (ViewHolder)convertView.getTag();
}

当convertView为空,即初始化创建时,我们就将生成的布局利用setTag()保存在convertView中,当convertView利用回收机制回收过来让我们再次使用时,我们通过getTag()将保存的布局取出来,重新将布局里的各个控件重新赋值就可以了。这里就利用了android-listView的回收机制。
再看”关注”的点击事件运行的怎样:
           点击                                         拉下去再拉回来                                    再往下拉

     

看第二张图,当拉下去再拉回来的时候,一切正常,但当我们再往下拉(第三张图),问题又出现了,明明没有点P-5,为什么关注反而是红色的!!!!!!

这是因为,P-5用的是P-1回收来的convertView!!!而P-1的convertView的布局里“关注”是红色的。所以只要回收机制在,我们就没有办法改变从P-1回收来的convertView里的图片布局,除非人为的将其重置!

理解了这个问题以后,我们想想解决办法。
首先申请一个arrayList  attentionArr变量,保存用户点击“关注”的ITEM的position,然后在绘制当前ITEM时,根据这个position是否在attentionArr里来判断是不是将“关注”重新变红。

代码如下:

  1. @Override  
  2. public View getView(final int position, View convertView, ViewGroup parent) {  
  3.       
  4.     System.out.println(”position:”+position+“   convertView:”+convertView);  
  5.     ViewHolder holder = null;  
  6.       
  7.     if (convertView == null) {  
  8.           
  9.     holder=new ViewHolder();      
  10.     convertView = mInflater.inflate(R.layout.item, null);  
  11.     holder.name = (TextView)convertView.findViewById(R.id.name);  
  12.     holder.info = (TextView)convertView.findViewById(R.id.info);  
  13.     holder.attentntion=(TextView)convertView.findViewById(R.id.attention);  
  14.     convertView.setTag(holder);       
  15.     }else {  
  16.       
  17.     holder = (ViewHolder)convertView.getTag();  
  18.     }  
  19.       
  20.     holder.name.setText((String)listItem.get(position).get(”name”));  
  21.     holder.info.setText((String)listItem.get(position).get(”info”));  
  22.     final TextView attention=holder.attentntion;  
  23.       
  24.     //根据当前position判断,重新制做样式  
  25.     if (attentionArr.contains(position)) {  
  26.         attention.setTextColor(Color.RED);  
  27.     }else {  
  28.         attention.setTextColor(Color.BLACK);  
  29.     }  
  30.   
  31.     holder.attentntion.setOnClickListener(new View.OnClickListener() {                
  32.         @Override  
  33.         public void onClick(View v) {  
  34.             // TODO Auto-generated method stub  
  35.             attention.setTextColor(Color.RED);  
  36.             attentionArr.add(position);//在点击时将position加入其中  
  37.         }  
  38.     });  
  39.     return convertView;  
  40. }  
@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    System.out.println("position:"+position+"   convertView:"+convertView);
    ViewHolder holder = null;

    if (convertView == null) {

    holder=new ViewHolder();    
    convertView = mInflater.inflate(R.layout.item, null);
    holder.name = (TextView)convertView.findViewById(R.id.name);
    holder.info = (TextView)convertView.findViewById(R.id.info);
    holder.attentntion=(TextView)convertView.findViewById(R.id.attention);
    convertView.setTag(holder);     
    }else {

    holder = (ViewHolder)convertView.getTag();
    }

    holder.name.setText((String)listItem.get(position).get("name"));
    holder.info.setText((String)listItem.get(position).get("info"));
    final TextView attention=holder.attentntion;

    //根据当前position判断,重新制做样式
    if (attentionArr.contains(position)) {
        attention.setTextColor(Color.RED);
    }else {
        attention.setTextColor(Color.BLACK);
    }

    holder.attentntion.setOnClickListener(new View.OnClickListener() {              
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            attention.setTextColor(Color.RED);
            attentionArr.add(position);//在点击时将position加入其中
        }
    });
    return convertView;
}
理解代码难度不大,首先在OnClickListener时,将position加入到attentionArr数组中,然后在getView里,判断当前position是不是用户点击过的,即是否包含在attentionArr数组中,如果是,则将“关注”置为红色,否则置为初始色,黑色。


源码地址:http://download.csdn.net/detail/harvic880925/7320141 不要分,仅供分享

源码说明:根据本文的顺序,分为三个源码,第一个即全部重新创建convertView版,第二个是利于回收机制,将holderView保存于convertView中,然后再取出来的那版,最后一个,是基于第二个的基础上修改的,也是本篇的最终版。


请大家尊重原创者版权,转载请标明出处:http://blog.csdn.NET/harvic880925/article/details/25335957 不胜感激!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值