使用自定义BaseAdapter从ListView中删除项目

时间:2011-01-04 02:48:23

标签: android listview android-listview

我使用自定义的BaseAdapter在ListView上显示项目。这些项只是ArrayList中的字符串。

列表项上有一个删除按钮(大红色X),我想从ArrayList中删除该项,并通知ListView自行更新。

但是,我尝试过的每个实现都会获得神秘的位置编号,因此例如单击项目2的删除按钮将删除项目5。它似乎几乎完全是随机的。

需要注意的一点是元素可能会重复,但必须保持相同的顺序。例如,我可以将“爱尔兰语”两次作为元素3和7。

我的代码如下:

private static class ViewHolder {
        TextView lang;
        int position;
}

public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.language_link_row, null);
        holder = new ViewHolder();
        holder.lang = (TextView)convertView.findViewById(R.id.language_link_text);
        holder.position = position;

        final ImageView deleteButton = (ImageView) 
                convertView.findViewById(R.id.language_link_cross_delete);
        deleteButton.setOnClickListener(this);

        convertView.setTag(holder);
        deleteButton.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.lang.setText(mLanguages.get(position));

    return convertView;
}

我稍后尝试通过抓取标记来检索已删除元素的位置,但它始终是列表中的错误位置。这里给出的位置没有明显的模式,它似乎总是随机的。

// The delete button's listener
public void onClick(View v) {

    ViewHolder deleteHolder = (ViewHolder) v.getTag();
    int pos = deleteHolder.position;

    ...
    ...
    ...
}

我很乐意从ArrayList中删除该项并让ListView自行更新,但我得到的位置不正确所以我不能这样做。

请注意,我首先在getView方法中使用了deleteButton clickListener,并使用'position'删除了值,但我遇到了同样的问题。

任何建议都表示赞赏,这真让我烦恼。

3 个答案:

答案 0 :(得分:5)

您每次都必须设置位置。您的实现仅在创建视图时设置位置。但是,当视图被回收时(当convertView不为null时),位置将不会设置为正确的值。

    public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.language_link_row, null);
        holder = new ViewHolder();
        holder.lang = (TextView)convertView.findViewById(R.id.language_link_text);

        final ImageView deleteButton = (ImageView) 
                convertView.findViewById(R.id.language_link_cross_delete);
        deleteButton.setOnClickListener(this);

        convertView.setTag(holder);
        deleteButton.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.lang.setText(mLanguages.get(position));
    holder.position = position;
    return convertView;
}

答案 1 :(得分:0)

你需要实现OnItemClickListener接口,并删除onItemClick方法中的项,方法的一个参数就是位置。

答案 2 :(得分:0)

我的最终解决方案是使用Greg接受的答案和以下内容:

  • 将持有人存储在HashMap中,项目位置为键(在构造函数中初始化为空)

    私人HashMap mHolders;

  • 将此用作onClickListener方法:

public void onClick(View v) {
    ViewHolder deleteHolder = (ViewHolder) v.getTag();
    int pos = deleteHolder.position;
    mHolders.remove(pos);

    ViewHolder currentHolder;

    // Shift 'position' of remaining languages 
    // down since 'pos' was deleted
    for(int i=pos+1; i<getCount(); i++){
        currentHolder = mHolders.get(i);
        currentHolder.position = i-1;
    }
    mLanguages.remove(pos);
    notifyDataSetChanged();
}

[请原谅奇怪的格式。代码嵌入无法正常工作]