zoukankan      html  css  js  c++  java
  • ListView中含有Button时setOnclickListener应写在Adapter的什么地方

    做Android开发,ListView是最常见不过了,因此对于ListView的自定义Adapter写法,应该也非常的熟悉,高效的Adapter编码,会使得携带大量ListView的数据展现显得非常容易。关于Adapter的写法,网上也有很多的例子,在此不再唠叨。为了提高ListView重绘时对已有对象的复用大抵是这样的:

     

    1. @Override  
    2. public View getView(final int position, View convertView, ViewGroup parent) {  
    3.     ViewHolder holder = null;  
    4.     if (convertView == null) {  
    5.         convertView = View.inflate(mContext, R.layout.listview_item, null);  
    6.         holder = new ViewHolder();  
    7.         holder.no = (TextView) convertView.findViewById(R.id.no);  
    8.         holder.click = (TextView) convertView.findViewById(R.id.click);  
    9.         convertView.setTag(holder);  
    10.     } else {  
    11.         holder = (ViewHolder) convertView.getTag();  
    12.     }  
    13.     String value = list.get(position);  
    14.     holder.no.setText(value);  
    15.       
    16.     OnClick listener = new OnClick(position);  
    17.     holder.click.setOnClickListener(listener);  
    18.       
    19.     Log.d(TAG,  
    20.             "position is " + position + " listener is "  
    21.                     + listener.toString());  
    22.     return convertView;  
    23. }  

    在这里我们讨论的是在ListView当中含有需要处理OnClick事件的写法,之前也写过一篇关于ListView当中含有Spinner的处理情况,这篇文章讲了如何处理Spinner的Onlick事件和对其状态的保持。虽然Onclick事件处理的比较高效,但是在方法上还有待提高。以下文章将列举出网上关于ListView中含有Onclick事件需要处理的普遍写法和本文的重点推荐高效写法。

     

    普遍写法:

     

    1. package com.yang.listviewclick.adapter;  
    2.   
    3. import java.util.List;  
    4.   
    5. import android.content.Context;  
    6. import android.util.Log;  
    7. import android.view.View;  
    8. import android.view.ViewGroup;  
    9. import android.view.View.OnClickListener;  
    10. import android.widget.BaseAdapter;  
    11. import android.widget.TextView;  
    12.   
    13. import com.yang.listviewclick.R;  
    14.   
    15. public class IneffectiveListViewAdapter extends BaseAdapter {  
    16.     private Context mContext;  
    17.     private List<String> list = null;  
    18.   
    19.     private static final String TAG = "ListViewAdapter";  
    20.   
    21.     public IneffectiveListViewAdapter(Context mContext, List<String> list) {  
    22.         this.mContext = mContext;  
    23.         this.list = list;  
    24.     }  
    25.   
    26.     @Override  
    27.     public int getCount() {  
    28.         return list.size();  
    29.     }  
    30.   
    31.     @Override  
    32.     public Object getItem(int position) {  
    33.         return list.get(position);  
    34.     }  
    35.   
    36.     @Override  
    37.     public long getItemId(int position) {  
    38.         return 0;  
    39.     }  
    40.   
    41.     class ViewHolder {  
    42.         TextView no;  
    43.         TextView click;  
    44.     }  
    45.   
    46.     @Override  
    47.     public View getView(final int position, View convertView, ViewGroup parent) {  
    48.         ViewHolder holder = null;  
    49.         if (convertView == null) {  
    50.             convertView = View.inflate(mContext, R.layout.listview_item, null);  
    51.             holder = new ViewHolder();  
    52.             holder.no = (TextView) convertView.findViewById(R.id.no);  
    53.             holder.click = (TextView) convertView.findViewById(R.id.click);  
    54.             convertView.setTag(holder);  
    55.         } else {  
    56.             holder = (ViewHolder) convertView.getTag();  
    57.         }  
    58.         String value = list.get(position);  
    59.         holder.no.setText(value);  
    60.         //问题出在这里,对于每次重绘,都新建了一个listener对象进行处理  
    61.         OnClick listener = new OnClick(position);  
    62.         holder.click.setOnClickListener(listener);  
    63.           
    64.         Log.d(TAG,  
    65.                 "position is " + position + " listener is "  
    66.                         + listener.toString());  
    67.         return convertView;  
    68.     }  
    69.   
    70.     class OnClick implements OnClickListener {  
    71.         private int position;  
    72.         public OnClick(int position){  
    73.             this.position = position;  
    74.         }  
    75.         @Override  
    76.         public void onClick(View v) {  
    77.             Log.d(TAG, list.get(position));  
    78.         }  
    79.     }  
    80. }  

    这种写法能够实现基本功能,即在点击某个组件时,它能够准确的定位到所点击的那个条目,并作出相应的处理。那么这是一种高效的写法吗?我们打印以下它的listener.

     


    大家知道

     

    1. position is 19 listener is com.yang.listviewclick.adapter.IneffectiveListViewAdapter$OnClick@4057f250  

    @后面的值是这个对象的HashCode,对于不同的对象来说,其HashCode是不同的,而这里打印出来的所有HashCode都不相同,说明每次拖动ListView,其会对每个条目重新申请一个对象,而且这些对象不是复用的,是全新的对象。你可以想象以下,如果有一千个条目,这拖动一次就是一千个对象,而且你再回到顶部又是一千个对象,效率可见一斑。

     

    推荐写法:

     

    1. package com.yang.listviewclick.adapter;  
    2.   
    3. import java.util.List;  
    4.   
    5. import com.yang.listviewclick.R;  
    6.   
    7. import android.content.Context;  
    8. import android.util.Log;  
    9. import android.view.View;  
    10. import android.view.View.OnClickListener;  
    11. import android.view.ViewGroup;  
    12. import android.widget.BaseAdapter;  
    13. import android.widget.TextView;  
    14.   
    15. public class EffectiveListViewAdapter extends BaseAdapter {  
    16.     private Context mContext;  
    17.     private List<String> list = null;  
    18.   
    19.     private static final String TAG = "ListViewAdapter";  
    20.   
    21.     public EffectiveListViewAdapter(Context mContext, List<String> list) {  
    22.         this.mContext = mContext;  
    23.         this.list = list;  
    24.     }  
    25.   
    26.     @Override  
    27.     public int getCount() {  
    28.         return list.size();  
    29.     }  
    30.   
    31.     @Override  
    32.     public Object getItem(int position) {  
    33.         return list.get(position);  
    34.     }  
    35.   
    36.     @Override  
    37.     public long getItemId(int position) {  
    38.         return 0;  
    39.     }  
    40.   
    41.     class ViewHolder {  
    42.         TextView no;  
    43.         TextView click;  
    44.     }  
    45.   
    46.     @Override  
    47.     public View getView(final int position, View convertView, ViewGroup parent) {  
    48.         ViewHolder holder = null;  
    49.         OnClick listener = null;  
    50.         if (convertView == null) {  
    51.             convertView = View.inflate(mContext, R.layout.listview_item, null);  
    52.             holder = new ViewHolder();  
    53.             holder.no = (TextView) convertView.findViewById(R.id.no);  
    54.             holder.click = (TextView) convertView.findViewById(R.id.click);  
    55.             listener = new OnClick();//在这里新建监听对象  
    56.             holder.click.setOnClickListener(listener);  
    57.             convertView.setTag(holder);  
    58.             convertView.setTag(holder.click.getId(), listener);//对监听对象保存  
    59.         } else {  
    60.             holder = (ViewHolder) convertView.getTag();  
    61.             listener = (OnClick) convertView.getTag(holder.click.getId());//重新获得监听对象  
    62.         }  
    63.         String value = list.get(position);//设置监听对象的值  
    64.         holder.no.setText(value);  
    65.         listener.setPosition(position);  
    66.         Log.d(TAG,  
    67.                 "position is " + position + " listener is "  
    68.                         + listener.toString());  
    69.         return convertView;  
    70.     }  
    71.   
    72.     class OnClick implements OnClickListener {  
    73.         int position;  
    74.   
    75.         public void setPosition(int position) {  
    76.             this.position = position;  
    77.         }  
    78.   
    79.         @Override  
    80.         public void onClick(View v) {  
    81.             Log.d(TAG, list.get(position));  
    82.         }  
    83.     }  
    84.   
    85. }  

    打印以下Listener

     



    大家可以看到,这里监听对象实现了复用。每次滑动都是第一次创建的监听对象的复用。

    实现这种机制的关键就是,使用convertView.setTag(holder.click.getId(), listener);对已有的对象进行保存,同时在使用时,使用listener = (OnClick) convertView.getTag(holder.click.getId())再获得这些对象。同时对这些复用的对象赋予不同的值listener.setPosition(position);。好了,今天就说到这里,测试项目的下载地址如下。

  • 相关阅读:
    Unique Binary Search Trees 解答
    Unique Paths II 解答
    Unique Paths 解答
    Maximum Subarray 解答
    Climbing Stairs 解答
    House Robber II 解答
    House Robber 解答
    Valid Palindrome 解答
    Container With Most Water 解答
    Remove Duplicates from Sorted List II 解答
  • 原文地址:https://www.cnblogs.com/LiaoHao/p/3366055.html
Copyright © 2011-2022 走看看