【问题标题】:ListView adapter onClickListener for list item updateListView 适配器 onClickListener 用于列表项更新
【发布时间】:2018-04-18 20:58:45
【问题描述】:

我知道这已经被问过很多次了。但是在尝试了许多解决方案后,我无法成功实施。

我正在制作一个包含多个Views 的自定义布局列表。其中一个视图是ImageView,我希望它在用户单击它时更改其图标。

我使用的ListAdapter类如下:

public class PetitionListAdapter extends BaseAdapter {

    ViewHolder holder = null;

    private LayoutInflater inflater;
    private ArrayList<CustomObject> objects;

    private class ViewHolder {
        ImageView ivsign;
    }

    public PetitionListAdapter(Context context, ArrayList<CustomObject> objects) {
        inflater = LayoutInflater.from(context);
        this.objects = objects;
    }

    public int getCount() {
        return objects.size();
    }

    public CustomObject getItem(int position) {
        return objects.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = inflater.inflate(R.layout.petition_list_layout_beta, null);
            holder.ivsign = convertView.findViewById(R.id.ivsign);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.ivsign.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ImageView img = v.findViewById(R.id.ivsign);
                img.setImageResource(R.drawable.icon_after_click);
            }
        });
        return convertView;
    }
}

这样做,clickListener 可以工作,但不是那个特定的 imageview,而是随机更改许多 imageview 的图标。我知道它是因为 viewHolder。但是我怎样才能正确地做到这一点呢?

我也用过:-

imgViewArray[位置] = holder.textView1;

在“onListItemClickListener”内。这样做会根据需要更改该位置的图标,但是在滚动并再次返回该行后,它再次更改为默认图标。我知道这是因为那一行被回收了。

【问题讨论】:

  • 使用您在代码中提到的数据集中的位置更新位置,然后notify适配器了解更改。

标签: android listview onclicklistener android-viewholder


【解决方案1】:

是的,你当然遇到了这个问题。为什么?因为当滚动列表视图时,您所有的convert views 都被重用了,每个convertView 被用来显示另一个CustomObject。这意味着如果您更改了第一行图像,滚动后,重用first-row convertView 的行将image 显示为clicked row。那么,如何解决呢?您必须将项目的位置保存在 CustomObject 中,例如:

 public View getView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        holder = new ViewHolder();
        convertView = inflater.inflate(R.layout.petition_list_layout_beta, null);
        holder.ivsign = convertView.findViewById(R.id.ivsign);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    final CustomObject object = listCustomObject.get(position);
    holder.ivsign.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ((ImageView)v).setImageResource(R.drawable.icon_after_click);
            object.saveResourceId(R.drawable.icon_after_click); // save your resource to use after scrolling.
        }
    });
    // display resouce base on what's saved or display default image.
    holder.ivSign.setImageResource(object.getSavedResourceId()); 
    return convertView;
}

【讨论】:

  • 成功了!如果我做得对,请检查 CustomObject 类? public class CustomObject { private int resId = R.drawable.ic_sign; public CustomObject() {} public String getProp9() { return prop9; } public void saveResourceId(int rid) { this.resId = rid; } public int getSavedResourceId() { return resId; } }
【解决方案2】:

我认为您的问题来自您的onClickListener。您在ViewHolder 中为ImageView 设置它,然后在onClick 方法中设置v.findViewById。

你应该做的是

ImageView img = (ImageView) convertView.findViewById(R.id.ivsign);

然后

img.setOnClickListener(.......);

这对我有用,所以如果您在实施时遇到任何问题,请告诉我。

【讨论】:

  • 问题仍然存在,即更改随机 imageView 图标。
【解决方案3】:

这不是一个好习惯。在OnItemClick 中,您应该更改列表使用的对象列表,然后调用notifyDataSetChanged()。在getView(...) 中,您应该简单地让 listView 反映列表中的值。 这样,当列表刷新时,视图的状态保持不变。

【讨论】:

  • 刷新列表不是从开始(从第一行)再次显示数据吗?实际上,当用户单击 imageView 然后继续滚动时,我希望更改图标(就像单击 facebook 上的“Like”按钮一样)。如果答案是“否”,那么我肯定会使用它。
猜你喜欢
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多