sam_k
sam_k

Reputation: 6023

Items inside GridView Getting loaded again when Scroll up and down

I'm using a GridView to show a number of images thumbnails of Images So User can choose any one of them and i will show that image in full screen. Each item of the grid is consisted by an ImageView Only, Image is retrieved from remote server.

When an item is touched, another activity is started to show image in full screen.

Here i used Universal Image Loader. and Here i used same way for Gridview as like this class which is part of Universal Image Loader.

I thought everything was going right, until I've noticed that some items were getting repeated and loading Again when I scrolls the screen.

So i put the displayimage logic in convertview== null part so now Whenever I scroll down trough the grid, and then back, items change itś position and get duplicated. Items imageview(Thumbnails) are duplicated in so many items but its actual content is different i can see that when i click on the item. And now Scrolling is too slow rather than first code.

So My main problems are

If i using first code :

1) If i used 1st code than Images(Items) are getting loaded again and again when i scroll down or scroll up.

If i am using Second Code :

2) If I used second code than items (Image thumbnails) are shows duplicated and shows as other image's thumbnail. 3) Gridview Scrolling is too slow.

Code : 1

public class ImageAdapter extends BaseAdapter {
    ArrayList<GallaryImage> imageList = null;
    private Context context;

    private class ViewHolder {
        public ImageView image;
        public ProgressBar pb;
    }

    public ImageAdapter(final Context context,
            final ArrayList<GallaryImage> imageAttributesList) {
        this.imageList = imageAttributesList;
        this.context = context;

    }

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

    @Override
    public GallaryImage getItem(final int position) {
        return imageList.get(position);
    }

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

    @Override
    public View getView(final int position, final View convertView,
            final ViewGroup parent) {
        View view = convertView;
        ViewHolder holder = null;
        if (convertView == null) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater
                    .inflate(R.layout.item_grid_image, parent, false);
            holder = new ViewHolder();
            holder.pb = (ProgressBar) view.findViewById(R.id.pb_grid_image);
            holder.image = (ImageView) view.findViewById(R.id.grid_image);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
        display(holder.image, imageList.get(position).mImageUrl, holder.pb);
        return view;
    }

    /**
     * @param img
     * @param url
     * @param spinner
     */
    public void display(ImageView img, String url, final ProgressBar spinner) {
        imageLoader.displayImage(url, img, options,
                new ImageLoadingListener() {
                    @Override
                    public void onLoadingStarted(String imageUri, View view) {
                        spinner.setVisibility(View.VISIBLE);
                    }

                    @Override
                    public void onLoadingFailed(String imageUri, View view,
                            FailReason failReason) {
                        spinner.setVisibility(View.GONE);

                    }

                    @Override
                    public void onLoadingComplete(String imageUri,
                            View view, Bitmap loadedImage) {
                        spinner.setVisibility(View.GONE);
                    }

                    @Override
                    public void onLoadingCancelled(String imageUri,
                            View view) {

                    }

                });
    }

    /**
     * @param updateData
     */
    public void updatedData(ArrayList<GallaryImage> imgList) {
        this.imageList = imgList;
        notifyDataSetChanged();
    }
}

Code : 2

private static final String TAG = "[Photography: ImageGridActivity]";
private DisplayImageOptions options;
private GridView mGridView = null;
ArrayList<GallaryImage> mGridViewImagesList;
private ImageAdapter mImageAdapter = null;
private String mImageUrl = null;
private String mGallaryTitle = null;

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_image_grid);
    options = new DisplayImageOptions.Builder()
            .showImageOnFail(R.drawable.ic_error)
            .showStubImage(R.drawable.photo_default).cacheOnDisc()
            .bitmapConfig(Bitmap.Config.RGB_565).build();

    final Bundle bundle = getIntent().getExtras();
    if (bundle != null) {
        mImageUrl = bundle.getString(Constants.GALLARY_FETCH_URL);

        mGallaryTitle = bundle.getString(Constants.GALLARY_TYPE);
        if (mGallaryTitle != null) {

            Locale loc = Locale.getDefault();
            TextView tvTitleText = (TextView) findViewById(R.id.tv_title_bar_text);
            tvTitleText.setText(mGallaryTitle.toUpperCase(loc));
        }
        mGridView = (GridView) findViewById(R.id.gridview);

        mGridViewImagesList = Utility.getImagesList(mImageUrl,
                ImageGridActivity.this);

        if (mGridViewImagesList != null && !mGridViewImagesList.isEmpty()) {
            mImageAdapter = new ImageAdapter(ImageGridActivity.this,
                    mGridViewImagesList);
            ((GridView) mGridView).setAdapter(mImageAdapter);
        } else {
            // did refresh after the previous images are loaded in the
            // gridview.
            if (Utility.checkConnection(ImageGridActivity.this)) {
                Log.i(TAG,
                        "Wifi/Internet Connection found , have to parse the xml");

                final FetchImagesAsyncTaskFeed asyncTask = new FetchImagesAsyncTaskFeed(
                        true);
                asyncTask.execute(mImageUrl);

            }

        }

        mGridView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(final AdapterView<?> parent,
                    final View view, final int position, final long id) {

                if (mGridViewImagesList != null
                        && !mGridViewImagesList.isEmpty()) {
                    startImagePagerActivity(mGridViewImagesList, position);
                } else {
                    Log.d(TAG, "There is no image about this grid image");
                }
            }
        });

    }

}

/**
 * back button key event
 */
private void goBack() {
    finish();
    // overridePendingTransition(R.anim.slide_in_right,
    // R.anim.slide_out_right);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        goBack();
        return true;
    }
    return super.onKeyUp(keyCode, event);
}

/**
 * @param position
 */
private void startImagePagerActivity(
        final ArrayList<GallaryImage> mImageAttributesList,
        final int position) {
    String[] urls = new String[mImageAttributesList.size()];
    final Intent intent = new Intent(this, ImagePagerActivity.class);
    intent.putExtra(Constants.GALLARY_IMAGE_POSITION_BUNDLE_KEY, position);
    for (int i = 0; i < mImageAttributesList.size(); i++) {
        urls[i] = mImageAttributesList.get(i).mImageUrl;
    }
    intent.putExtra(Constants.GALLARY_IMAGES_IMAGE_BUNDLE_KEY, urls);
    startActivity(intent);
}

public class ImageAdapter extends BaseAdapter {
    ArrayList<GallaryImage> imageList = null;

    private class ViewHolder {
        public ImageView image;
        public ProgressBar pb;
    }

    public ImageAdapter(final Context context,
            final ArrayList<GallaryImage> imageAttributesList) {
        this.imageList = imageAttributesList;

    }

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

    @Override
    public GallaryImage getItem(final int position) {
        return imageList.get(position);
    }

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

    @Override
    public View getView(final int position, final View convertView,
            final ViewGroup parent) {
        View view = convertView;
        final ViewHolder holder;
        if (convertView == null) {
            view = getLayoutInflater().inflate(R.layout.item_grid_image,
                    parent, false);
            holder = new ViewHolder();
            holder.pb = (ProgressBar) view.findViewById(R.id.pb_grid_image);
            holder.image = (ImageView) view.findViewById(R.id.grid_image);
            view.setTag(holder);
            display(holder.image, imageList.get(position).mImageUrl, holder.pb);
        } else {
            holder = (ViewHolder) view.getTag();
        }
        return view;
    }

    /**
     * @param img
     * @param url
     * @param spinner
     */
    public void display(ImageView img, String url, final ProgressBar spinner) {
        imageLoader.displayImage(url, img, options,
                new ImageLoadingListener() {
                    @Override
                    public void onLoadingStarted(String imageUri, View view) {
                        spinner.setVisibility(View.VISIBLE);
                    }

                    @Override
                    public void onLoadingFailed(String imageUri, View view,
                            FailReason failReason) {
                        spinner.setVisibility(View.GONE);

                    }

                    @Override
                    public void onLoadingComplete(String imageUri,
                            View view, Bitmap loadedImage) {
                        spinner.setVisibility(View.GONE);
                    }

                    @Override
                    public void onLoadingCancelled(String imageUri,
                            View view) {

                    }

                });
    }

    /**
     * @param updateData
     */
    public void updatedData(ArrayList<GallaryImage> imgList) {
        this.imageList = imgList;
        notifyDataSetChanged();
    }
}

/**
 * @author
 * 
 */
private class FetchImagesAsyncTaskFeed extends
        AsyncTask<String, Void, String> {
    ProgressBar progressbar = null;
    boolean showProgress = false;

    public FetchImagesAsyncTaskFeed(boolean showProgress) {
        this.showProgress = showProgress;
    }

    @Override
    protected void onPreExecute() {
        if (showProgress) {

            progressbar = (ProgressBar) ImageGridActivity.this
                    .findViewById(R.id.gv_progressBar);
            progressbar.setVisibility(View.VISIBLE);

        }
    }

    @Override
    protected String doInBackground(final String... urls) {
        try {
            final String imageUrl = urls[0];
            final GridViewImagesXMLHandler mGallaryXMLHandler = new GridViewImagesXMLHandler();
            mGridViewImagesList = mGallaryXMLHandler.getImages(imageUrl);
            if (mGridViewImagesList != null
                    && !mGridViewImagesList.isEmpty()) {
                Utility.setImagesInfromation(imageUrl, mGridViewImagesList,
                        ImageGridActivity.this);
            }
        } catch (final Exception e) {
            Log.e(TAG, "Exception in fetch images from the url", e);
        }
        return null;
    }

    @Override
    protected void onPostExecute(final String result) {
        if (mGridViewImagesList != null && !mGridViewImagesList.isEmpty()) {
            if (mImageAdapter != null) {
                mImageAdapter.updatedData(mGridViewImagesList);
                // mPullRefreshGridView.onRefreshComplete();
            } else {
                mImageAdapter = new ImageAdapter(ImageGridActivity.this,
                        mGridViewImagesList);
                ((GridView) mGridView).setAdapter(mImageAdapter);
            }
        }
        // mPullRefreshGridView.onRefreshComplete();
        if (progressbar != null) {
            progressbar.setVisibility(View.GONE);
        }
    }
}

GridView XML file

<GridView
    android:id="@+id/gridview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_below="@id/title_bar"
    android:alwaysDrawnWithCache="true"
    android:gravity="center"
    android:horizontalSpacing="4dip"
    android:numColumns="4"
    android:scrollingCache="true"
    android:smoothScrollbar="true"
    android:stretchMode="columnWidth"
    android:verticalSpacing="4dip" />

Please help me to sort out this problem. Thanks for any help.

Thanks

Upvotes: 2

Views: 5040

Answers (3)

Vijay Vankhede
Vijay Vankhede

Reputation: 3058

I had also similar problem. I solved it by using ImageAware. And also use UIL 1.9+ version.

     ImageAware imageAware = new ImageViewAware(vh.imageView, false);
     imageLoader.displayImage("drawable://"
     + item.drawableId, imageAware);

Upvotes: 1

Ash
Ash

Reputation: 1241

If you use Code 2, I think you should do something like this:

Get the ProgressBar and ImageView before you check if (convertView == null):

Image imageView = (ImageView) convertView.findViewById(R.id.grid_image);
ProgressBar progressBar = (Progressbar) convertView.findViewById(R.id.pb_grid_image);
if (convertView == null) {
    convertView = getLayoutInflater().inflate(R.layout.item_grid_image,
            parent, false);
    holder = new ViewHolder();
    holder.pb = (ProgressBar) view.findViewById(R.id.pb_grid_image);
    holder.image = (ImageView) view.findViewById(R.id.grid_image);
    view.setTag(holder);
    display(holder.image, imageList.get(position).mImageUrl, holder.pb);
} else {
    holder = (ViewHolder) view.getTag();
}

imageView = holder.imageView;
return view;

Upvotes: -2

Tofeeq Ahmad
Tofeeq Ahmad

Reputation: 11975

Because we are setting Background of ImageView everytime we comes inside getView(). getView() call every time when one Item becomes visible to user (Its happening when you are scrolling). As BaseAdapter recycle the view so we are compelled to set data after if and else condition. Save all images inside one DiskLruCache to load them faster and check if it present there then show from there else download it and add it to DiskLruCache

Upvotes: 4

Related Questions