简体   繁体   English

多听众

[英]Multiple listeners

I've a question about ListView and listeners. 我有一个关于ListView和侦听器的问题。 Suppose i have a listview in my app. 假设我的应用程序中有一个listview。 Each item of it contains a checkbox. 它的每个项目都包含一个复选框。 And i've the following code: 我有以下代码:

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

    CheckBox checkbox = (CheckBox)v.findViewById(R.id.checkbox);

    checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener(){

        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // some code
        }               
    });

}

As you can see I set setOnCheckedChangeListener every time when getView method is called. 如您所见,每次调用getView方法时,我都会设置setOnCheckedChangeListener。 So is it right way to set listener? 那么设置监听器的正确方法是吗? Or should I set it once? 还是应该设置一次? Is it bad in terms of performance? 在性能方面不好吗? Or it doesn't matter? 还是没关系? And if I set the listener multiple times whether it will overwrite previous listener or will i have multiple listeners for this event? 而且,如果我多次设置侦听器,它将覆盖先前的侦听器还是该事件有多个侦听器?

Is it bad in terms of performance? 在性能方面不好吗? Or it doesn't matter? 还是没关系?

It does not matter. 不要紧。 The setter just assign the object. 设置者只分配对象。

And if I set the listener multiple times whether it will overwrite previous listener or will i have multiple listeners for this event? 而且,如果我多次设置侦听器,它将覆盖先前的侦听器还是该事件有多个侦听器?

you will have just one for each instance of the checkbox upon you called setOnCheckedChangeListener . 调用setOnCheckedChangeListener时,每个复选框实例只有一个。 The ListView is particular case due of its recycling mechanism ListView的特殊情况是由于其回收机制

Each listener that you set will overwrite the previous one (if any). 您设置的每个监听器都将覆盖前一个监听器(如果有)。
Setting a listener, or anything else, will consume a super small amount of time, however here you're also creating a new anonymous class which will take longer. 设置侦听器或其他任何方法都将花费极少的时间,但是在这里,您还将创建一个新的匿名类,该类将花费更长的时间。

For the maximum performance, I would make a few adjustments: 为了获得最佳性能,我将进行一些调整:

  1. Use convertView s to cache the views 使用convertView缓存视图
  2. Use ViewHolder pattern to avoid multiple findViewById calls 使用ViewHolder模式来避免多次findViewById调用
  3. Use a single listener for all checkboxes and set it only on the cached views (if convertView == null ) 对所有复选框使用单个侦听器,并仅在缓存的视图上进行设置(如果convertView == null
  4. Save the position of the item that the CheckBox is located in as the CheckBox's tag 将CheckBox所在项目的位置保存为CheckBox的标签

Here's an example: 这是一个例子:

private static class ViewHolder {
    CheckBox checkBox;
}

private CompoundButton.OnCheckedChangeListener mCheckListener = new CompoundButton
        .OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        Log.e("TAG", "CheckBox position: " + buttonView.getTag());
    }
};

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        /* Inflate the layout here */

        holder = new ViewHolder();
        holder.checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);
        /* Find other views in you layout here */

        holder.checkBox.setOnCheckedChangeListener(mCheckListener);
        // Set the holder as tag, so you can fetch it later for re-use
        convertView.setTag(holder);
    } else {
        // Fetch the holder
        holder = (ViewHolder) convertView.getTag();
    }

    // Set the checkbox position
    holder.checkBox.setTag(position);

    return convertView;
}

If you're not familiar with using convertViews and the ViewHolder pattern you should watch The World of ListView that explains it all. 如果您不熟悉convertViewsViewHolder模式的使用,则应观看解释了这一切的World of ListView

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM