2

我正在尝试使用RecylerView谷歌最近推出的。我在那里有一组行,现在是 7-8 行,每一行都有一个我从服务器获取的图像。为此,我正在使用 Picasso 库,但这对我不起作用。我不确定我是否遗漏了什么或配置了什么。

屏幕正确显示每一行的默认图像,但不会从服务器下载图像,如果服务器响应缓慢,我会等待超过 5 分钟,但事实并非如此。

代码

public DemoRecyclerAdapter(List<DemoRowModel> items, int itemLayout, final Context mContext) {
    this.items = items;
    this.itemLayout = itemLayout;
    this.mContext = mContext;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    DemoRowModel item = items.get(position);

    holder.mDemoNameTextView.setText(item.getDemoName());
    holder.mDemoDateTextView.setText(item.getDemoDate());

    Target mTarget = new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
            holder.mImageView.setImageBitmap(bitmap);
        }

        @Override
        public void onBitmapFailed(Drawable drawable) {
            Logger.d(TAG, "Failed! Bitmap could not downloaded.");
        }

        @Override
        public void onPrepareLoad(Drawable drawable) {
        }
    };

    Picasso.Builder builder = new Picasso.Builder(mContext);
    Picasso picasso = builder.downloader(new OkHttpDownloader(mContext) {
        @Override
        protected HttpURLConnection openConnection(Uri uri) throws IOException {
            HttpURLConnection connection = super.openConnection(uri);
            // fetch the auth value
            SharedPreferences mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext.getApplicationContext());
            connection.setRequestProperty(Constant.HEADER_X_API_KEY, mSharedPreferences.getString(SharedPreferenceKeys.JSESSIONID, ""));
            return connection;
        }
    }).build();

    picasso.load(item.getImagePath()).into(mTarget);

    // here set the value
    holder.itemView.setTag(item);

}

提前致谢。

4

2 回答 2

5

如果您使用Target's - 它们应该是强引用对象。mTaget在您的类中创建字段并从方法中移动Target的初始化。onBindViewHolder

编辑:将身份验证密钥保存在安全的地方,例如keystore. 不要将它们保存在 中SharedPreferences,这是一种不好的做法。

更新:

1)创建自定义目标类

public class CommonImageTarget implements Target {
    private final ImageView imageView;

    public CommonImageTarget(final ImageView imageView) {
        this.imageView = imageView;
    }

    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        this.imageView.setImageBitmap(bitmap);
    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {
        Logger.d(TAG, "Failed! Bitmap could not downloaded.");
    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {
    }
}

2)创建自定义ImageView

public class ImageViewWithTarget extends ImageView{
    /**
     * Required for Bitmap loading using Picasso. Picasso uses weak references in into() method and Target's are garbage collected, save them in object.
     */
    private Target target;

    public ImageViewWithTarget(Context context) {
        super(context);
    }

    public ImageViewWithTarget(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ImageViewWithTarget(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public Target getTarget() {
        return target;
    }

    public void setTarget(Target target) {
        this.target = target;
    }
}

3)当您在viewHolder中初始化您的imageView时,在其中设置自Target定义

viewHolder.mImageView.setTarget(new CommonImageTarget(viewHolder.mImageView));

4) 更新ViewHolder

public class ViewHolder{
       ...
       private ImageViewWithTarget mImageView;
   }

5)在您的布局中替换ImageViewImageViewWithTarget

6) 更新onBindViewHolder方法

picasso.load(item.getImagePath()).into(viewHolder.mImageView.getTarget());

现在每个ImageView人都会拥有自己的Target对象,并且Target不会被垃圾收集。

另一种方法:将Target对象保存在ViewHolder.

于 2014-11-20T09:55:05.260 回答
2

您应该使用 ImageView 的方法 setTag(Object tag)

这个案例:

……

Target mTarget = new Target() {
    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
        holder.mImageView.setImageBitmap(bitmap);
    }

    @Override
    public void onBitmapFailed(Drawable drawable) {
        Logger.d(TAG, "Failed! Bitmap could not downloaded.");
    }

    @Override
    public void onPrepareLoad(Drawable drawable) {
    }
};

holder.mImageView.setTag(mTarget);// Target isn't garbage collected

Picasso.Builder builder = new Picasso.Builder(mContext);

……

它对我有用

于 2015-05-25T09:41:26.483 回答