3

我有一个带有图像、一对 TextViews 和一个复选框的 ListViews 的自定义 row_item。据我了解,由于 checkBox 是一个可聚焦元素,它会从 listView 中窃取焦点,因此 OnListItemClicked 永远不会被触发,除非我将每个 row_item 设置为不可点击并且我阻止后代的可聚焦性。

然后,为了管理复选框更改,我在适配器 getView 方法中为我的复选框设置了“OnCheckedChangeListener”。

这是一种不好的做法吗?(因为每次调用 getView 时我都在创建新的侦听器)还有其他方法可以做到这一点吗?

我附上了一些代码,以便更容易理解我的意思。

getView 方法:(在 arrayAdapter 内)

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

    /** recycling views */
    View row = convertView;
    PregoHolder holder = null;

    if(row == null)
    {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new PregoHolder();
        holder.imgIcon = (ImageView)row.findViewById(R.id.thumbnail);
        holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
        holder.txtNews = (TextView)row.findViewById(R.id.txtNews);
        holder.chBox = (CheckBox) row.findViewById(R.id.checkBox);

        row.setTag(holder);
    }
    else
    {
        holder = (PregoHolder)row.getTag();
    }

    Prego Prego = data[position];
    holder.txtTitle.setText(Prego.title);
    holder.imgIcon.setImageResource(Prego.icon);
    holder.txtNews.setText(Prego.news);
    holder.chBox.setChecked(Prego.checked);

    /** wiring up Listeners... 
     * (works fine but we are creating new listener each time)
     * (Done like this because of the custom list view focusable issue)
     */

    holder.chBox.setOnCheckedChangeListener(new OnCheckedChangeListener(){

        @Override
        public void onCheckedChanged(CompoundButton arg0, boolean checked) {
            /** Getting the view position in the ListView */
            ListView parent = (ListView)(arg0.getParent()).getParent();
            int pos = parent.getPositionForView(arg0);

            if (checked){
                checkedPregons[pos] = true;
                pregonsChecked++;
            }
            else if (!checked){
                checkedPregons[pos] = false;
                pregonsChecked--;
            }

            Toast.makeText(context, pregonsChecked+" is/are checked", Toast.LENGTH_SHORT).show();
        }
    });

    row.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
            //mMode = ((Activity)context).startActionMode(new PregonsActionModes());
            ListView parent = (ListView)v.getParent();
            int pos = parent.getPositionForView(v);
            Toast.makeText(context, "getView should show prego "+pos,Toast.LENGTH_SHORT).show();

        }
    });

    return row;
}

提前致谢。

4

1 回答 1

3

我想可能有更好的方法来解决它,但这不是我会失眠的事情。您的方法已被许多新旧 Android 开发人员广泛实施,这只是一种简单自然的方式。此外,请记住,ListView只有一次在屏幕上可以看到尽可能多的行(并且getView在您滚动时不断调用),所以您在任何给定时间谈论 8 - 12 个制作对象(显然完全猜测),所以你的瓶颈不会在这里。事实上,根据我需要修改的对象在哪里,我什至没有考虑它。

但是OnCheckedChangeListener在 a中使用ListView是我强烈警告的事情。就像我说getView的那样,在滚动和制作每一行时都会调用它。这个经过检查的已更改侦听器正在被触发,尽管它绝对不能保证每行getView只调用一次,但实际上我保证不会。因此,这些代码块可能会被 wazoo 激发,即使您可能只打算CheckBox手动处理复选框。输入一个相对更密集的命令notifyDataSetChanged(),你会看到你ListView从这个现象中被锁定。

解决方案是简单地使用复选框onClickListener并检查isChecked()内部。

于 2012-12-29T17:32:44.790 回答