arrayAdapter getView 方法内的侦听器

2024-04-24

我有一个用于 ListView 的自定义 row_item,其中包含图像、一对 TextView 和一个复选框。 据我了解,由于 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;
}

提前致谢。


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

But using OnCheckedChangeListener in a ListView我强烈警告不要这样做。就像我说的,getView在滚动和制作每一行时都会调用它。这个已检查的已更改侦听器在创建时就会被解雇,尽管绝对不能保证getView被称为只是once对于每一行,事实上我保证不是这样。因此,这些代码块可能会被激发,即使您可能只打算CheckBox框勾选是手动处理的。放置一个相对更密集的命令,例如notifyDataSetChanged()你会看到你的ListView锁定此现象。

解决方案是简单地使用复选框onClickListener相反并检查isChecked() inside.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

arrayAdapter getView 方法内的侦听器 的相关文章

随机推荐