GridView中的项目在向上和向下滚动时再次加载

时间:2013-05-15 03:20:48

标签: android android-layout android-gridview baseadapter universal-image-loader

我正在使用GridView显示图像的大量图像缩略图,因此用户可以选择其中任何一个,我将以全屏显示该图像。 网格的每个项目仅由ImageView组成,从远程服务器检索图像。

触摸某个项目时,会启动另一项活动以全屏显示图像。

我在这里使用了Universal Image Loader。在这里,我使用与Gridview相同的方式,就像this类一样,它是Universal Image Loader的一部分。

我认为一切都是正确的,直到我注意到有些项目重复并在我滚动屏幕时再次加载。

所以我将displayimage逻辑放在convertview== null部分,所以现在每当我向下滚动网格,然后返回时,项目会改变它的位置并得到重复。项目imageview(缩略图)在如此多的项目中重复,但其实际内容不同,我可以看到当我点击该项目时。现在滚动速度太慢而不是第一个代码。

所以我的主要问题是

如果我使用第一个代码:

1)如果我使用第一个代码而不是图像(项目)在我向下滚动或向上滚动时反复加载。

如果我使用第二代码:

2)如果我使用第二个代码而不是项目(图像缩略图),则显示重复的节目并显示为其他图像的缩略图。 3)Gridview滚动太慢了。

代码: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();
    }
}

代码: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文件

<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" />

请帮我解决这个问题。谢谢你的帮助。

由于

3 个答案:

答案 0 :(得分:4)

因为我们每次进入 getView()时都会设置ImageView的背景。每次当一个项目对用户可见时(在滚动时发生), getView()会调用。 当BaseAdapter回收视图时,我们被迫在if和else之后设置数据。将所有图片保存在一个 DiskLruCache 中以更快地加载它们并检查它是否存在,然后从那里显示下载并将其添加到 {{ 3}}

答案 1 :(得分:1)

我也有类似的问题。我使用ImageAware解决了这个问题。并且还使用UIL 1.9+版本。

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

答案 2 :(得分:-2)

如果你使用Code 2,我认为你应该这样做:

在检查if(convertView == null)之前获取ProgressBar和ImageView:

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;