Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListView Changing Items During Scroll

I am implementing a ListFragment using a custom ArrayAdapter to populate the list. Each row item has an ImageView and three TextViews. Data is being parsed via XML and the images are being async loaded.

The problem I am having is that the ListView populates and looks good, but there is a problem when scrolling. I can fit 7 items on the screen at once. When I scroll to the 8th, it changes suddenly so the next row that should be appearing. It only does it on rows divisible by 8 (ie. rows 8, 16, 24, etc).

I'm using the ViewHolder pattern to ensure good speed with this ListView. I figure the problem lies in there somewhere, but I have searched around and it appears I am doing this pattern correctly and I have run out of things to check in order to resolve this issue. What am I doing wrong? Thanks!

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    MyViewHolder holder;
    if (row == null) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        row = inflater.inflate(R.layout.browse_result_list_item, null, false);
        holder = new MyViewHolder();
        holder.adTitle = (TextView) row.findViewById(R.id.adTitle);
        holder.region = (TextView) row.findViewById(R.id.region);
        holder.time = (TextView) row.findViewById(R.id.time);
        holder.thumbnail = (ImageView) row.findViewById(R.id.browseThumbnail);
        row.setTag(holder);
    } else {
        holder = (MyViewHolder) row.getTag();
    }
    SearchResult result = mObjects.get(position);

    holder.adTitle.setText(result.getTitle().substring(0, result.getTitle().length()-3)); // three ... at the end, remove them
    holder.region.setText(result.getRegion());
    holder.time.setText(result.getPostingTime());

    // Download the image thumbnail
    ArrayList<String> urls = result.getImageUrls();
    if (urls.size() > 0)
        download(urls.get(0), holder.thumbnail);
    else // No image for this post, put a placeholder
        holder.thumbnail.setImageResource(R.drawable.ic_action_picture);

    return row;
}

private static class MyViewHolder {
    public static TextView adTitle;
    public static TextView region;
    public static TextView time;
    public static ImageView thumbnail;
}

Edit: I found the solution thanks to @frozenkoi. Ended up being the static variables inside the ViewHolder causing problems. They are now simply public and the class is static and the issue has bee solved.

like image 975
Alex Helms Avatar asked Mar 22 '23 19:03

Alex Helms


1 Answers

First of all define in getView() method into convertView=null; and comment else condition in this method and add int type = getItemViewType(position);. Also remove static keyword from each View item like Textview, ImageView in ViewHolder class.

NOTE: override getViewTypeCount() and getItemViewType() in your adapter.

if(convertView == null){
 switch (type) {
            case 0:
                  //First view[Row layout]
            break;
            case 1:
                 //Second view[Row layout]
            break;

            //another Case here....

   convertView.setTag(holder);

  //remove else part when used convertView =null;
        /*else {
        holder = (MyViewHolder) row.getTag();
    }*/

} 

@Override
    public int getItemViewType(int position) {
        // TODO Auto-generated method stub
        map = list.get(position); 
        message_type = map.get("message_type");
        if (message_type.equalsIgnoreCase("TEXT")) {
            return 0;
        } else {
            return 1;
        }

    }

    @Override
    public int getViewTypeCount() {
        // TODO Auto-generated method stub
        if (getCount() != 0)
            return getCount();
        return 2;
    }

Do it now! Done!

like image 149
Jaydip Radadiya Avatar answered Mar 24 '23 10:03

Jaydip Radadiya