【问题标题】:Items repeating when scrolling in ListView在 ListView 中滚动时重复的项目
【发布时间】:2015-06-03 21:31:37
【问题描述】:

我在列表视图中使用自定义适配器。当我在我的数组列表中打印出我的数据时,它会正确存储,尽管当我滚动项目时会重复。我知道我的 getView 方法有点混乱,但为什么它不能正确表示我的数组列表数据“oslist”?

这是我的适配器代码:

public class WXYCAdapter extends BaseAdapter {

private FragmentActivity context;
private ArrayList<HashMap<String, String>> oslist;
private ArrayList<HashMap<String, String>> heartList;

private LayoutInflater mInflater;

private final static int STREAM_LAYOUT = 0;
private final static int TALKSET_LAYOUT = 1;
private final static int BREAKPOINT_LAYOUT = 2;
private final static int PLAYCUT_LAYOUT = 3;
private final static int NULL_LAYOUT = 4;

String URL;
ViewHolder holder;

public WXYCAdapter(FragmentActivity context, ArrayList<HashMap<String, String>> oslist) {
    this.context = context;
    this.oslist = oslist;
    this.mInflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}


@Override
public int getCount() {
    return this.oslist.size();
}

@Override
public Object getItem(int position) {
    return null;
}

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

@Override
public int getItemViewType(int position) {

    int RETURN_LAYOUT = NULL_LAYOUT;

    switch (oslist.get(position).get("layoutType")) {
        case "LiveStream":
            RETURN_LAYOUT = STREAM_LAYOUT;
            break;

        case "Playcut":
            RETURN_LAYOUT = PLAYCUT_LAYOUT;
            break;

        case "Talkset":
            RETURN_LAYOUT = TALKSET_LAYOUT;
            break;

        case "Breakpoint":
            RETURN_LAYOUT = BREAKPOINT_LAYOUT;
            break;
    }

    return RETURN_LAYOUT;

}

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

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

    holder = null;
    int type = getItemViewType(position);

    if (convertView == null) {
        holder = new ViewHolder();
        switch (type) {
            case STREAM_LAYOUT:
                convertView = mInflater.inflate(R.layout.listview_cell, null);

                holder.cell_image = (ImageView) convertView.findViewById(R.id.cell_image);
                holder.cell_image.setImageResource(R.drawable.boombox);

                holder.song = (TextView) convertView.findViewById(R.id.song);
                holder.artist = (TextView) convertView.findViewById(R.id.artist);

                holder.song.setEnabled(false);
                holder.song.setMaxHeight(0);

                holder.artist.setEnabled(false);
                holder.artist.setMaxHeight(0);

                convertView.setTag(holder);
                break;

            case TALKSET_LAYOUT:
                convertView = mInflater.inflate(R.layout.listview_cell, null);

                holder.cell_image = (ImageView) convertView.findViewById(R.id.cell_image);
                holder.cell_image.setImageBitmap(null);
                holder.cell_image.setEnabled(false);
                holder.cell_image.setMaxHeight(0);
                holder.cell_image.setMaxWidth(0);

                holder.song = (TextView) convertView.findViewById(R.id.song);
                holder.artist = (TextView) convertView.findViewById(R.id.artist);
                holder.song.setText("Talkset");
                holder.artist.setText(null);

                holder.artist.setEnabled(false);
                holder.artist.setMaxHeight(0);

                convertView.setTag(holder);
                break;

            case BREAKPOINT_LAYOUT:
                convertView = mInflater.inflate(R.layout.listview_cell, null);

                holder.cell_image = (ImageView) convertView.findViewById(R.id.cell_image);
                holder.cell_image.setImageBitmap(null);
                holder.cell_image.setEnabled(false);
                holder.cell_image.setMaxHeight(0);
                holder.cell_image.setMaxWidth(0);

                holder.song = (TextView) convertView.findViewById(R.id.song);

                //holder.song.setTypeface(Typeface.createFromAsset(context.getAssets(), "default.ttf"));

                holder.artist = (TextView) convertView.findViewById(R.id.artist);
                holder.song.setText("Breakpoint");
                holder.artist.setText(null);
                holder.artist.setEnabled(false);
                holder.artist.setMaxHeight(0);


                long l = Long.parseLong(oslist.get(position).get("hour"));

                Calendar calendar = Calendar.getInstance();
                calendar.setTimeInMillis(l);
                calendar.setTimeInMillis(l * 1000);

                int hour = calendar.get(Calendar.HOUR);

                convertView.setTag(holder);
                break;

            case PLAYCUT_LAYOUT: //Playcut


                convertView = mInflater.inflate(R.layout.listview_cell, null);


                //holder.cell_image = (ImageView) convertView.findViewById(R.id.cell_image);

                //holder.cell_image.setImageResource(R.drawable.no_album_art);

                holder.song = (TextView) convertView.findViewById(R.id.song);
                holder.artist = (TextView) convertView.findViewById(R.id.artist);

                holder.song.setText(oslist.get(position).get("songTitle"));
                holder.artist.setText(oslist.get(position).get("artistName"));

                convertView.setTag(holder);
                break;
            case NULL_LAYOUT:
                convertView.setTag(holder);
                break;

        }


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

    return convertView;

}

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



public static class ViewHolder {
    public TextView textView, song, artist;


    public ImageView cell_image;
    public Button playButton;
}

}

【问题讨论】:

  • 我很确定您的示例代码可以从当前的 198 行(几乎 6K 字符)中减少。请参阅How to create a Minimal, Complete, and Verifiable example
  • 我修好了!我只需要将 switch case 移到 if-else 语句下方。不完全确定为什么......但如果有人想解释,我很想学习

标签: java android listview scroll adapter


【解决方案1】:

Listview 应该重用一个视图。因此,相同的视图可以用于列表的其他项目。

主要问题是只有当视图为空时才更改视图的内容

错误的方式

If(convertView == null) {
    //Inflate view
    // Change view content
}

由于视图可以重复使用,它并不总是为空。

如您所说,在您将 switch 语句移到空条件之外后,问题已得到解决。

这样,视图内容将始终根据当前项更改(这是正确的)

正确的方式

If(convertView == null) {
    // inflate it
}
// Change view content

这在开始时也让我感到困惑...... 视图被重用了。但是你应该相应地改变它的内容。

【讨论】:

  • 这个答案是正确的。我唯一要添加的是在If(convertView == null) { // inflate it } else { holder = (ViewHolder) convertView.getTag(); }
猜你喜欢
  • 1970-01-01
  • 2015-01-20
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-13
  • 1970-01-01
相关资源
最近更新 更多