在Android应用开发过程中经常会用到ListView,并且每次在item中都要对点击事件进行监听。在给按钮添加OnClickListener时,一般会下意识的在getView()中找到每一个Button并new一个OnClickListener分配给这个Button,并将position赋给这个Button的监听事件。但是当数据量很大时new出这么多的监听器势必会对内存添加压力。然而每个Listener的功能完全一样,Listener里面所需要知道的只是一个position而已。那么怎样更好的利用内存呢?
既然每个Listener的功能一样,那么完全可以用单例模式构造一个Listener。如下所示:
1 class MyOnClickListener implements View.OnClickListener { 2 private static MyOnClickListener instance = null; 3 private MyOnClickListener() {} 4 public static MyOnClickListener getInstance() { 5 if (instance == null) 6 instance = new MyOnClickListener(); 7 return instance; 8 } 9 @Override 10 public void onClick(View view) { 11 //TODO: do something here 12 } 13 }
而在getView()方法中,获取到button实例之后,只需要通过button.setOnclickListener(MyOnClickListener.getInstance());对按钮社会自监听。这样的话每个按钮必然用的是同一个Listener对象。
但是我们需要的不仅如此,很多时候我们还需啊哟知道具体是哪个position的Button被点击了,我们需要根据position在Listener里面做出不一样的事情。
想要在Listener内部了解外部控件的属性,我们首先想到的是传参,但是由于我们的Listener使用的是单利模式,每个按钮忘Listener里面传的参数必然会覆盖前一个按钮传来的参数。于是我们的解决方案只剩下一种,那就是通过onClick函数的参数(View view)来获取该信息,也就是Button了。我们可以将position信息存储到Button中的Tag中,利用button.setTag(position);
那么接下来就是在Adapter中的getView方法中做相应的操作了:
1 // ... 2 @Override 3 public View getView(int position, View converView, ViewGroup parentView) { 4 Handler handler = null; 5 View view = convertView; 6 if(convertView == null) { 7 view = LayoutInflater.from(activity).inflate(R.layout.item_list, null); 8 handler= new Handler(); 9 handler.button = view.findViewById(R.id.item_list_btn); 10 view.setTag(handler); 11 } else { 12 handler = (Handler) view.getTag(); 13 } 14 // ... 15 handler.button.setTag(position); 16 handler.button.setOnclickListener(MyOnClickListener.getInstance()); 17 return view; 18 } 19 } 20 class Handler { 21 Button button; 22 }
最后在MyOnClickListener中的onClick方法中添加点击事件即可:
1 // ... 2 @Override 3 public void onClick(View v) { 4 int position = (Integer) ((Button) v).getTag(); 5 // ... 6 }
附上item_list.xml文件的代码:
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" > 6 <Button 7 android:id="@+id/item_list_btn" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:text="点击" /> 11 </RelativeLayout>
这样我们就实现了使用一个Listener对ListView中不同Item的按钮事件监听进行处理。如果还想传递出position等其他数据时,则需要自定义Button类,再在我们自定义的Button中添加我们需要的参数方法。
---------------------------------------------------
欢迎每位访客提出宝贵的意见。