1

我有一个关于 ListView 和听众的问题。假设我的应用程序中有一个列表视图。它的每个项目都包含一个复选框。我有以下代码:

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
        }               
    });

}

如您所见,每次调用getView方法时,我都会设置 setOnCheckedChangeListener。那么设置监听器是否正确?还是我应该设置一次?在性能方面是不是很糟糕?还是没关系?如果我多次设置监听器,它是否会覆盖以前的监听器,或者我是否会有多个监听器来处理这个事件?

4

2 回答 2

1

在性能方面是不是很糟糕?还是没关系?

不要紧。setter 只是分配对象。

如果我多次设置监听器,它是否会覆盖以前的监听器,或者我是否会有多个监听器来处理这个事件?

在您调用复选框时,您将只有一个复选框setOnCheckedChangeListener。由于其回收机制,这ListView是特殊情况

于 2015-01-31T11:29:13.220 回答
1

您设置的每个侦听器都将覆盖前一个侦听器(如果有)。
设置侦听器或其他任何东西会消耗极少的时间,但是在这里您还要创建一个新的匿名类,这将花费更长的时间。

为了获得最佳性能,我会做一些调整:

  1. 使用convertViews 缓存视图
  2. 使用ViewHolder模式避免多次findViewById调用
  3. 对所有复选框使用单个侦听器并仅在缓存视图上设置它(如果convertView == null
  4. 将 CheckBox 所在的 item 的位置保存为 CheckBox 的标签

这是一个例子:

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;
}

如果您不熟悉使用convertViewsViewHolder模式,您应该观看解释这一切的 ListView 世界。

于 2015-01-31T11:47:45.970 回答