当使用带有ViewHolder的getView()时滚动时,ListView中的文本会搞乱

时间:2012-10-14 20:25:24

标签: android android-listview android-cursoradapter

我有一个奇怪的问题,我的ListView将正确显示最初创建视图时填充的列表项,但是当我开始滚动时,位置会在某些项上发生变化,并且不会反映它们在清单。

这是我的代码:

private class CustomCursorAdapter extends CursorAdapter {

    LayoutInflater mInflater;

    public CustomCursorAdapter(Context context, Cursor c, int flags) {
        super(context, c, flags);
        this.mContext = context;

        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @SuppressWarnings("static-access")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.assignment_list_item, parent, false);
            holder = new ViewHolder();
            holder.colorStrip = (ColorStrip) convertView.findViewById(R.id.assignment_list_color_strip);
            holder.titleLabel = (TextView) convertView.findViewById(R.id.list_title);
            holder.descriptionLabel = (TextView) convertView.findViewById(R.id.list_description);
            holder.dueLabel = (TextView) convertView.findViewById(R.id.list_due);

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

        assignmentsCursor.moveToPosition(position);
        String title = assignmentsCursor.getString(1);
        short course = assignmentsCursor.getShort(2);
        String desc = assignmentsCursor.getString(3);
        long due = assignmentsCursor.getLong(4);

        holder.titleLabel.setText("Pos: " + position + " | " + title);
        holder.colorStrip.setColor(colors.get(course));
        convertView.setBackgroundColor(colorsLight.get(course));
        String dueString = getDateString(due);
        holder.dueLabel.setText(dueString);
        holder.descriptionLabel.setText(desc);

        return convertView;
    }

    @Override
    public void bindView(View arg0, Context arg1, Cursor arg2) {}

    @Override
    public View newView(Context arg0, Cursor arg1, ViewGroup arg2) { return null; }

    @Override
    public boolean hasStableIds() { return true; }

    @Override
    public int getViewTypeCount() { return 2; }
}

你可以在这里看到我的问题的视频:http://youtu.be/KzyTLSsDeJk在视频中你可以看到位置7的列表项在我滚动时正在改变一堆,然后列表似乎重新开始于0项目编号8. ListView 应该显示的是“Pos:0”,“Pos:1”......“Pos:8”,“Pos:9”,等等。

颜色也从位置8到列表末尾混乱。背景颜色总是应该是列表项左侧的条带的较轻版本。

修改 在视频中,您可以看到getView被传递的位置(在每个列表项中标题TextView中反映出来)在最初可见的内容(通过“Pos:6 | ...”)上很好。屏幕(没有滚动),但是一旦我向下滚动,接下来出现的一切都搞砸了。

以下是每个列表项中第一个TextView的表示(括号中的内容是我的注释):

Pos:0 |阅读第1章(好)
Pos:1 |填写知识框(好)
Pos:2 |关于第1章的论文(好)
Pos:4 |阅读第2章(好)
Pos:5 |在粘合剂中加入更多纸张(好)
Pos:6 |做第1课(好)
Pos:## | [滚动时会有所不同](在Pos:7时正确启动,但随着我滚动得更多,它变化很大)
Pos:0 |阅读第1章(应为Pos:8)
Pos:1 |填写知识框(应该是Pos:9)

Pos:##是最初只在屏幕外的项目,但当我滚动位置编号更改时(请参阅视频)。

编辑2:这是我的ViewHolder类:

private static class ViewHolder {
    private static ColorStrip colorStrip;
    private static TextView titleLabel;
    private static TextView descriptionLabel;
    private static TextView dueLabel;

    public ViewHolder() {}
}

编辑3:只是为了踢,我停止使用我的ViewHolder(并且每次使用运行findViewById()的低效方法)并且我的问题都消失了。所有TextView都被分配了适当的值,颜色看起来也很好。我的ViewHolder实现可能有什么问题?

3 个答案:

答案 0 :(得分:0)

我认为要分配游标值,你应该使用bindView()和newView()方法而不是getView()。

答案 1 :(得分:0)

可能是因为您没有使用CursorAdapter,因为您应该使用它。在CursorAdapter中,您必须对newView()内的视图进行充气并返回view,该bindView()将传递给CursorAdapter,以便使用光标中的数据绑定视图。您可以查看here.中的演示项目,以确保如何实施CursorAdapter。您还可以查看{{1}}的许多教程,其中一个是this one

答案 2 :(得分:-1)

从这样的getView()方法中删除if条件。

 public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder;


        convertView = mInflater.inflate(R.layout.assignment_list_item, parent, false);
        holder = new ViewHolder();
        holder.colorStrip = (ColorStrip) convertView.findViewById(R.id.assignment_list_color_strip);
        holder.titleLabel = (TextView) convertView.findViewById(R.id.list_title);
        holder.descriptionLabel = (TextView) convertView.findViewById(R.id.list_description);
        holder.dueLabel = (TextView) convertView.findViewById(R.id.list_due);

        convertView.setTag(holder);

    assignmentsCursor.moveToPosition(position);
    String title = assignmentsCursor.getString(1);
    short course = assignmentsCursor.getShort(2);
    String desc = assignmentsCursor.getString(3);
    long due = assignmentsCursor.getLong(4);

    holder.titleLabel.setText("Pos: " + position + " | " + title);
    holder.colorStrip.setColor(colors.get(course));
    convertView.setBackgroundColor(colorsLight.get(course));
    String dueString = getDateString(due);
    holder.dueLabel.setText(dueString);
    holder.descriptionLabel.setText(desc);

    return convertView;
}