Percy Ankleshwaria
Percy Ankleshwaria

Reputation: 21

How to maintain state of ListView items when scrolled?

I am using a listview with following view as list item

  1. TextView
  2. ImageView (showing attachment icon)

I am using custom adapter that extends ArrayAdapter and uses ViewHolder, and in custom adapter I check for condition if an attachment exists. If true, I make ImageView visible. Everything works fine, but as I scroll the ImageView disappear.

public class NoticeListAdapter  extends ArrayAdapter<String>{

    private final Activity context;
    private  List<String> img_url = new ArrayList<String>();
    private  List<String>  heading = new ArrayList<String>();
    private  List<Long>  createdDate = new ArrayList<Long>();
    private  List<String>  documentCategoryId = new ArrayList<String>();
    Date date = new Date();

    public NoticeListAdapter(Activity context, List<String> img_url, List<String> heading, List<Long> createdDate, List<String> documentCategoryId) {
        super(context, R.layout.attendance_list_item, heading);
        // TODO Auto-generated constructor stub
        this.context=context;
        this.img_url = img_url;
        this.heading = heading;
        this.createdDate = createdDate;
        this.documentCategoryId = documentCategoryId;
    }

    public static class ViewHolder {
        ImageView profilePicture;
        ImageView attachmentIcon;
        TextView txtemployeeName;
        TextView txtbulletinDate;
    }

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

        ViewHolder viewHolder;
        if(view == null){
            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            view = inflater.inflate(R.layout.notice_list_item, parent, false);
            viewHolder.profilePicture = (ImageView) view.findViewById(R.id.profilePic);
            viewHolder.txtemployeeName = (TextView) view.findViewById(R.id.employeeName);
            viewHolder.txtbulletinDate = (TextView) view.findViewById(R.id.bulletinDate);
            viewHolder.attachmentIcon = (ImageView) view.findViewById(R.id.attachmentIcon);
            view.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder)view.getTag();
        }


        String description = heading.get(position);
        description = description.length()>40?description.substring(0,40)+"...":description;

        SharedPreferences pref = getContext().getSharedPreferences("authDetails", Context.MODE_PRIVATE);
        ImageLoader imageLoader = new ImageLoader(getContext());
        imageLoader.DisplayImage(pref.getString("base_url", "")+img_url.get(position), viewHolder.profilePicture);

        viewHolder.txtemployeeName.setText(description);
        viewHolder.txtbulletinDate.setText(DateUtils.getRelativeTimeSpanString(createdDate.get(position),  date.getTime(),  DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE));

        if(documentCategoryId.get(position).equalsIgnoreCase("0"))
            viewHolder.attachmentIcon.setVisibility(View.GONE);
        return view;
    }

}

Upvotes: 0

Views: 643

Answers (3)

VadymVL
VadymVL

Reputation: 5566

You have ViewHolder implementation problem in your code. You don't set holder result to not null view. And also, don't retrieve recently created holder.

Try to change:

 view.setTag(viewHolder);
 }else{
 viewHolder = (ViewHolder)view.getTag();
 }

to this

 view.setTag(viewHolder);
 }
 viewHolder = (ViewHolder)view.getTag();

and before return view;:

view.setTag(viewHolder);

Try this, fixed code:

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

    ViewHolder viewHolder;
    if(view == null){
        viewHolder = new ViewHolder();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        view = inflater.inflate(R.layout.notice_list_item, parent, false);
        viewHolder.profilePicture = (ImageView) view.findViewById(R.id.profilePic);
        viewHolder.txtemployeeName = (TextView) view.findViewById(R.id.employeeName);
        viewHolder.txtbulletinDate = (TextView) view.findViewById(R.id.bulletinDate);
        viewHolder.attachmentIcon = (ImageView) view.findViewById(R.id.attachmentIcon);
        view.setTag(viewHolder);
    }
    viewHolder = (ViewHolder)view.getTag();

    String description = heading.get(position);
    description = description.length()>40?description.substring(0,40)+"...":description;

    SharedPreferences pref = getContext().getSharedPreferences("authDetails", Context.MODE_PRIVATE);
    ImageLoader imageLoader = new ImageLoader(getContext());
    imageLoader.DisplayImage(pref.getString("base_url", "")+img_url.get(position), viewHolder.profilePicture);

    viewHolder.txtemployeeName.setText(description);
    viewHolder.txtbulletinDate.setText(DateUtils.getRelativeTimeSpanString(createdDate.get(position),  date.getTime(),  DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE));

    if(documentCategoryId.get(position).equalsIgnoreCase("0"))
        viewHolder.attachmentIcon.setVisibility(View.GONE);
    view.setTag(viewHolder);
    return view;
}

Upvotes: 0

Xcihnegn
Xcihnegn

Reputation: 11597

Just change your codes:

if(documentCategoryId.get(position).equalsIgnoreCase("0"))
        viewHolder.attachmentIcon.setVisibility(View.GONE);

to be:

if(documentCategoryId.get(position).equalsIgnoreCase("0"))
        viewHolder.attachmentIcon.setVisibility(View.GONE);
else
        viewHolder.attachmentIcon.setVisibility(View.VISIBLE);

Upvotes: 2

Kushal
Kushal

Reputation: 8498

This problem is from your custom ImageLoader implementation.

Paste your code, there is some bug which is not displaying image.

Alternatively, you can download image from URL and set it as source of profilePicture ImageView like this :

URL url = new URL(img_url.get(position));
Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
viewHolder.profilePicture.setImageBitmap(bmp);

Upvotes: 0

Related Questions