【问题标题】:Duplicate items in GridView when using ImageLoader library使用 ImageLoader 库时 GridView 中的重复项
【发布时间】:2012-09-09 14:21:13
【问题描述】:

我正在使用GridView 来显示ImageViews 的列表。图像通过ImageLoader 库从 Internet 加载。我还实现了一个自定义适配器(扩展 BaseAdapter):

public class ImagePreviewAdapter extends BaseAdapter {

    private Context mContext;

    private List<LastPost> mPosts = new ArrayList<LastPost>();

    private ImageLoader mImageLoader;

    private ImageLoadingListener mLoadingListener;

    public ImagePreviewAdapter(Context context, List<LastPost> posts, ImageLoadingListener listener) {
        this.mContext = context;
        this.mPosts = posts;
        this.mLoadingListener = listener;

        Activity activity = (Activity)mContext;
        this.mImageLoader = ((MeanwhileInRussia)activity.getApplication()).getImageLoader();
    }

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

    public LastPost getItem(int position) {
        return mPosts.get(position);
    }

    public long getItemId(int position) {
        LastPost post = mPosts.get(position);
        return Long.parseLong(post.getId());
    }

    public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;

        // if it's not recycled, initialize some attributes
        if (convertView == null) {
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(125, 125));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(0, 0, 0, 0);

            String imageLink = mPosts.get(position).getImageurl();
            DisplayImageOptions displayImgOptions = ImageLoaderConfigUtil
                .getDisplayImageOptions(mContext);

            if (mLoadingListener != null) {
                mImageLoader
                    .displayImage(imageLink, imageView, displayImgOptions, mLoadingListener);
           } else {
                mImageLoader.displayImage(imageLink, imageView, displayImgOptions);
           }

        } else {
            ImageView restoringView = (ImageView)convertView;
            imageView = restoringView;
        }

        return imageView;
    }
}

每次系统调用getView() 方法时,我都会创建一个新的ImageView 对象并要求ImageLoader 将图像放入其中(当然如果convertView == null)。对于 URL 的第一部分,一切正常。但我的问题从第二部分开始:GridView 中没有新图像,只有第一部分的副本...我意识到问题隐藏在 convertView == null 的某个地方:对于所有理论上的新元素,此检查始终等于错误的!而不是创建新对象并从 URL 加载图像,我的代码将一些 OLD 对象放入新位置。有趣的事实:getItemId(position) 方法为我的 LastPost 对象返回正确的 ID。这是否意味着我在适配器中有正确的 LastPosts 对象的视图不正确?

有什么建议吗?谢谢!

【问题讨论】:

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


    【解决方案1】:

    试试这个....

    public class ImagePreviewAdapter extends BaseAdapter 
    {
    
    private Context mContext;
    
    private List<LastPost> mPosts = new ArrayList<LastPost>();
    
    private ImageLoader mImageLoader;
    
    private ImageLoadingListener mLoadingListener;
    
    /**
     * Constructor
     * 
     * @param context
     * @param posts
     * @param listener - using for showing loading progress
     */
    public ImagePreviewAdapter(Context context, List<LastPost> posts, ImageLoadingListener listener) {
        this.mContext = context;
        this.mPosts = posts;
        this.mLoadingListener = listener;
    
        Activity activity = (Activity)mContext;
        this.mImageLoader = ((MeanwhileInRussia)activity.getApplication()).getImageLoader();
    }
    
    public int getCount() {
        return mPosts.size();
    }
    
    public LastPost getItem(int position) {
        return mPosts.get(position);
    }
    
    public long getItemId(int position) {
        LastPost post = mPosts.get(position);
        return Long.parseLong(post.getId());
    }
    
    /*
     * Create a new ImageView for each item referenced by the Adapter
     */
    public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;
    
        // if it's not recycled, initialize some attributes
        if (convertView == null) {
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(125, 125));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(0, 0, 0, 0);
    
        } 
       else 
          {
            ImageView restoringView = (ImageView)convertView;
            imageView = restoringView;
         }
            final String imageLink = mPosts.get(position).getImageurl();
            final DisplayImageOptions displayImgOptions = ImageLoaderConfigUtil
                .getDisplayImageOptions(mContext);
    
       if (mLoadingListener != null) 
        {
           mImageLoader.displayImage(imageLink, imageView,displayImgOptions,mLoadingListener);
           }
         else 
            {
                mImageLoader.displayImage(imageLink, imageView, displayImgOptions);
           }
    
        return imageView;
    }
    }
    

    【讨论】:

    • 如何访问 imageLink 在该位置,因为它包含在第一个条件中
    • 什么是俄罗斯的同时期?在这一行中 this.mImageLoader = ((MeanwhileInRussia)activity.getApplication()).getImageLoader();
    • MeanwhileInRussia 是应用程序类名。
    【解决方案2】:

    试试这个

    public View getView(int position, View convertView, ViewGroup parent) {
    
       ViewHolder holder = null;
        // if it's not recycled, initialize some attributes
        if (convertView == null) {
            holder = new ViewHolder();
            holder.image = new ImageView(mContext);
            holder.image.setLayoutParams(new GridView.LayoutParams(125, 125));
            holder.image.setScaleType(ImageView.ScaleType.CENTER_CROP);
            holder.image.setPadding(0, 0, 0, 0);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
    
        String imageLink = mPosts.get(position).getImageurl();
        DisplayImageOptions displayImgOptions = ImageLoaderConfigUtil.getDisplayImageOptions(mContext);
        mImageLoader.displayImage(imageLink, holder.image, displayImgOptions);
    
        return convertView;
    }
    
    
    protected class ViewHolder{
        ImageView image;
    }
    

    【讨论】:

    • convertView.setTag(holder) 提供强制关闭,因为在此位置 convertView 将始终为空
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    相关资源
    最近更新 更多