0

I am making an application that is kind of like instagram and therefore loads images from the internet. The images loaded come from Parse.com's backend service. What I want to be able to do is load a lot of items in a listview and prevent the listview from reloading the image when it comes into view. Basically I don't want images to refresh,I want them to stay in the listview even as I scroll.

OnCreate MainActivity

imageCache = new BitmapLruCache();
imageLoader = new ImageLoader(Volley.newRequestQueue(getApplicationContext()), imageCache);

PostsAdapter

public class PostsAdapter extends BaseAdapter implements StickyListHeadersAdapter {

    private Context context;
    public List<PostList> postList;

    public void add(PostList object,int position) {
        postList.add(position,object);
    }

    public PostsAdapter(Context context) {
        this.context=context;
        postList = new ArrayList<PostList>();
    }

    public int getCount() {
        return postList.size();
    }

    public PostList getItem(int position) {
        return postList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if(convertView == null){
            convertView = LayoutInflater.from(context).inflate(R.layout.posts_list, null);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
            }else{
            holder = (ViewHolder)convertView.getTag();
            holder.imageView.setImageUrl(null, imageLoader);
            }
        holder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // TODO Auto-generated method stub

                    postList.get(position).liked = isChecked;

            }
        });
        holder.imageView.setOnClickListener(new DoubleClickListener(){

            @Override
            public void onSingleClick(View v) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onDoubleClick(View v) {
                // TODO Auto-generated method stub
                holder.checkbox.setChecked(true);
                postList.get(position).liked = true;
            }
        });

        holder.checkbox.setChecked(postList.get(position).liked);
        holder.imageView.setSoundEffectsEnabled(false);
        holder.imageView.setImageUrl(postList.get(position).postPicture, imageLoader);
       return convertView;
    }

    @Override
    public View getHeaderView(int position, View convertView,
            ViewGroup parent) {
        // TODO Auto-generated method stub
        HeaderViewHolder HVH;
        if(convertView == null){
            convertView = LayoutInflater.from(context).inflate(R.layout.post_header_list, null);
            HVH = new HeaderViewHolder(convertView);
            convertView.setTag(HVH);
        }else{
            HVH = (HeaderViewHolder)convertView.getTag();
        } 
        CharSequence timeAgo = DateUtils.getRelativeTimeSpanString(
                Long.parseLong(postList.get(position).user),
                System.currentTimeMillis(), DateUtils.SECOND_IN_MILLIS);
        HVH.username.setText(timeAgo);
        return convertView;
    }

    @Override
    public long getHeaderId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    }
public abstract class DoubleClickListener implements OnClickListener {

    private static final long DOUBLE_CLICK_TIME_DELTA = 300;//milliseconds

    long lastClickTime = 0;

    @Override
    public void onClick(View v) {
        long clickTime = System.currentTimeMillis();
        if (clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA){
            onDoubleClick(v);
        } else {
            onSingleClick(v);
        }
        lastClickTime = clickTime;
    }

    public abstract void onSingleClick(View v);
    public abstract void onDoubleClick(View v);
}
 static class ViewHolder{
 NetworkImageView imageView;
 CheckBox checkbox;
    ViewHolder(View v){
            imageView = (NetworkImageView )v.findViewById(R.id.Posts_Image);
            checkbox = (CheckBox)v.findViewById(R.id.liked);
Rhynoboy2009
  • 140
  • 3
  • 11

1 Answers1

0

In Following function of NetworkImageView

@Override
protected void onDetachedFromWindow() {
    if (mImageContainer != null) {
        // If the view was bound to an image request, cancel it and clear
        // out the image from the view.
        mImageContainer.cancelRequest();
        setImageBitmap(null);
        // also clear out the container so we can reload the image if necessary.
        mImageContainer = null;
    }
    super.onDetachedFromWindow();
}

You will notice that, Image bitmap is being set to null, You can edit this in your library and hold the image for as long as you want ... But the HEAP size will grow large if you do that .../ So so keep some logic for cleaning bitmap when not needed

EDIT: For increasing cache size in file storage You can change value in DiskBasedCache file

/** Default maximum disk usage in bytes. */
private static final int DEFAULT_DISK_USAGE_BYTES = 10 * 1024 * 1024;

You can take a look at following post for allowed heap size Android heap size on different phones/devices and OS versions You can play with

 Runtime.getRuntime().maxMemory(); and 
 Runtime.getRuntime().freeMemory();

To decide when to start freeing the bitmaps. So instead of plainly saying

 setImageBitmap(null);    // You can say if only 30% is free let's start freeing memory

 if (Runtime.getRuntime().freeMemory() < Runtime.getRuntime().freeMemory()* 0.3)
      setImageBitmap(null);
Community
  • 1
  • 1
maaz
  • 204
  • 3
  • 5
  • Is there any other way you would suggest going about something like this? The app is basically supposed to run like Instagram,will this slow down performance? Is there a more efficient way? – Rhynoboy2009 Oct 25 '14 at 11:38
  • You can try increasing the Volley FileBasedCache Size for getting image from local flat files, – maaz Oct 25 '14 at 11:50
  • Also you can put some logic as when to discard the image from NetworkImageView, like when user has scrolled a good amount of items, remove the bitmap form the initial items – maaz Oct 25 '14 at 11:52
  • How would I go about doing this? Sorry,I'm just learning about Volley. – Rhynoboy2009 Oct 25 '14 at 12:10
  • Check my edited answer for file cache size increase, – maaz Oct 25 '14 at 12:54
  • There is one more thing about the ListView, It only store's a fixed number of view as much is needed to show to user, Rest is recycled as convertView Have a look at this : http://android.amberfog.com/?p=296 – maaz Oct 25 '14 at 13:18