向下滚动时,Android CustomListView更新的字段会重复

时间:2016-02-05 09:36:18

标签: android listview android-arrayadapter

我在customlist view中遇到了问题。

我有两个buttons和一个textVie w。添加和减去按钮。 单击Add按钮时,计数器应分别为+1和-1。

我使用了一个虚拟字符串来检查它是否实际更新textView。但问题是当我scroll down某些项目具有相同的价值时。

例如 第1项TextView设置为" HIII" 然后,如果我向下滚动11日,21日......也将设置为" HIII" 注意:显示的最大数量可以包含10个项目,因此当我向下滚动到第11个时,它被设置为" HII"。

public class CustomAdapter extends ArrayAdapter {
    Context context;
    LayoutInflater inflater;
    int resource;
    //ArrayList<Integer> count = new ArrayList<>();




    public CustomAdapter(Context context, int resource) {
        super(context, resource);
        this.context = context;
        this.resource = resource;

    }

    @Override
    public int getCount() {
        return 100;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
       ViewHolder mainHolder = null;
        if (convertView == null) {
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(resource, parent, false);
            Log.e("GET-VIEW", " Creating Views");
           final ViewHolder holder = new ViewHolder();
            holder.add = (Button) convertView.findViewById(R.id.add);
            holder.sub = (Button) convertView.findViewById(R.id.sub);
            holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
            holder.add.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    holder.textView.setText("HIII");
                }
            });
            convertView.setTag(holder);
        } else {
           mainHolder = (ViewHolder) convertView.getTag();
        }

        return convertView;
    }
}


class ViewHolder {

    Button add, sub;
    TextView textView;

}

请帮帮我。我想知道如何设置一个tag与另一个(我的意思是你知道你需要用另一个对象或视图设置标签)

由于

3 个答案:

答案 0 :(得分:1)

ListView回收视图。它会创建在向下滚动时重复使用的视图。

因此,每次调用setText()时都必须调用setOnClickListener()getView(),而不仅仅是在点击按钮时。

要实现您的目标,您必须将设置的文本数据存储在模型中,例如将位置映射到数据的SparseArray

public class CustomAdapter extends ArrayAdapter {
    Context context;
    LayoutInflater inflater;
    int resource;
    //ArrayList<Integer> count = new ArrayList<>();

    // Your data map by position
    SparseArray<String> data = new SparseArray<>();


    public CustomAdapter(Context context, int resource) {
        super(context, resource);
        this.context = context;
        this.resource = resource;

    }

    @Override
    public int getCount() {
        return 100;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
       final ViewHolder holder;
        if (convertView == null) {
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(resource, parent, false);
            Log.e("GET-VIEW", " Creating Views");
            holder = new ViewHolder();
            holder.add = (Button) convertView.findViewById(R.id.add);
            holder.sub = (Button) convertView.findViewById(R.id.sub);
            holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
            convertView.setTag(holder);
        } else {
           holder = (ViewHolder) convertView.getTag();
        }

        holder.textView.setText(data.get(position));
        holder.add.setOnClickListener( new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final String text = "HIII";
                data.put(position, text);
                holder.textView.setText(text);
                notifyDataSetChanged();
            }
        });

        return convertView;
    }
}

class ViewHolder {

    Button add, sub;
    TextView textView;

}

答案 1 :(得分:0)

在其他条件之后写你的onclick监听器。

holder.add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                holder.textView.setText("HIII");
            }
        });

答案 2 :(得分:0)

看一下你的getView函数:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
   ViewHolder mainHolder = null;
    if (convertView == null) {
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(resource, parent, false);
        Log.e("GET-VIEW", " Creating Views");
       final ViewHolder holder = new ViewHolder();
        holder.add = (Button) convertView.findViewById(R.id.add);
        holder.sub = (Button) convertView.findViewById(R.id.sub);
        holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
        holder.add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                holder.textView.setText("HIII");
            }
        });
        convertView.setTag(holder);
    } else {
       mainHolder = (ViewHolder) convertView.getTag();
    }

    return convertView;
}

仅在创建新的Viewholder时编辑持有者textViewadd按钮的内容。 listview第一次显示其项目时,将始终为所有可见单元格创建新视图(以及新的Viewholder)。 一旦向下滚动,适配器将采用一个现在不可见的单元格(可能是第一个单元格)并回收它以显示一个现在可见的单元格。在这种情况下,getView中的convertView将不再为null,因为视图已被回收。 因此,您应该在if语句之外处理所有文本更改和监听器等,以管理这两种情况(循环使用和新建)。 例如:

    if (convertView == null) {
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(resource, parent, false);
        Log.e("GET-VIEW", " Creating Views");
        final ViewHolder holder = new ViewHolder();
        holder.add = (Button) convertView.findViewById(R.id.add);
        holder.sub = (Button) convertView.findViewById(R.id.sub);
        holder.textView = (TextView) convertView.findViewById(R.id.numberTV);

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

    holder.textView.setText("");
    holder.add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                holder.textView.setText("HIII");
            }
        });

修改 要将数据保存在像Yaroslav Mytkalyk这样的稀疏数组中,建议这是一种更好的方法。 无论如何,你必须处理回收的意见。