【问题标题】:Attempting to remove item from ListView always removes the first item尝试从 ListView 中删除项目总是删除第一个项目
【发布时间】:2016-10-12 13:24:32
【问题描述】:

我有一个自定义适配器和一个列表,我可以在单击按钮时动态添加项目。每个列表行都有一个删除按钮(或图像)。那是我的自定义适配器类:

package com.ameer.easycooking;

import android.content.Context;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

/**
 * Created by ameer on 12/10/2016.
 */
public class IngredientAdapter extends ArrayAdapter<String> {
    private List<String> ingredientList;
    private Context context;

    public IngredientAdapter(List<String> ingredientList, Context context) {
        super(context, R.layout.ingredient_list_item, ingredientList);
        this.ingredientList = ingredientList;
        this.context = context;
    }

    public static class IngredientHolder {
        private TextView name;
        private ImageView remove;

        public IngredientHolder(TextView name, ImageView remove) {
            this.name = name;
            this.remove = remove;
        }

        public TextView getName() {
            return name;
        }

        public ImageView getRemove() {
            return remove;
        }
    }

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

        IngredientHolder holder;

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.ingredient_list_item, null);

            holder = new IngredientHolder((TextView) v.findViewById(R.id.ingredientName), (ImageView) v.findViewById(R.id.remove));

            holder.getRemove().setTag(position);

            holder.getRemove().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int index = (int) v.getTag();
                    Toast.makeText(context, ingredientList.get(index) + " removed", Toast.LENGTH_SHORT).show();
                    ingredientList.remove(index);
                    notifyDataSetChanged();
                }
            });

            v.setTag(holder);
        } else {
            holder = (IngredientHolder) v.getTag();
        }

        String ingredient = ingredientList.get(position);
        holder.name.setText(ingredient);

        return v;
    }
}

我的问题是,无论我添加多少项目或选择删除哪个项目,它总是删除 ListView 中的第一行而不是点击的那一行。

【问题讨论】:

  • 在 if/else 逻辑之后移动 holder.getRemove().setTag(position);
  • @Blackbelt 谢谢,它现在工作正常。 :)

标签: android listview


【解决方案1】:

您只会点击一次convertView == null,这就是您遇到此问题的原因。您应该在 if/else 语句之后设置 holder.getRemove().setTag(position);

【讨论】:

  • 没有 onClickListener。仅限holder.getRemove().setTag(position);
  • 是的,你说的是真的。
  • @Carnal 我是这样做的,它解决了我的问题。
【解决方案2】:

你不应该在你的 if 语句中设置你的点击监听器,因为你不知道什么时候会使用转换后的视图,并且点击的位置可能是错误的。因此,只需将点击侦听器移出 if 语句并删除 holder.getRemove().setTag(position) 语句即可:

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

    IngredientHolder holder;

    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.ingredient_list_item, null);
        holder = new IngredientHolder((TextView) v.findViewById(R.id.ingredientName), (ImageView) v.findViewById(R.id.remove));
        v.setTag(holder);
    } else {
        holder = (IngredientHolder) v.getTag();
    }

    String ingredient = ingredientList.get(position);
    holder.name.setText(ingredient);

    holder.getRemove().setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int index = (int) v.getTag();
            Toast.makeText(context, ingredientList.get(index) + " removed", Toast.LENGTH_SHORT).show();
            ingredientList.remove(index);
            notifyDataSetChanged();
        }
    });

    return v;
}

编辑: 或者正如 Blackbelt 所说,您可以简单地将 holder.getRemove().setTag(position); 语句移出 if 块。

【讨论】:

  • 是的,我按照 Blackbelt 所说的做了,现在可以了。但我有个问题。如果我选择按照您的建议进行操作,那么 int index = (int) v.getTag(); 将不再起作用,因为我不会为其设置标签,不是吗?
  • 是的,但是如果你在 if 块之外定义了点击监听器,那么你不需要设置标签。
【解决方案3】:

更好的方法可以使在 getView() 中传递的位置最终 public View getView(final int position, View convertView, ViewGroup parent) 并在点击监听器中使用该位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-23
    • 2022-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多