Using Picasso with Image Getter

六月ゝ 毕业季﹏ 提交于 2019-11-30 14:55:50

I couldn't get it to work with using Picasso's Target...

My workaround is:

  • use an AsyncTask for concurrency
  • use Picasso's get() method to load the image synchronously in the AsyncTask's background method

Like this:

public class PicassoImageGetter implements Html.ImageGetter {

final Resources resources;

final Picasso pablo;

final TextView textView;

public PicassoImageGetter(final TextView textView, final Resources resources, final Picasso pablo) {
    this.textView  = textView;
    this.resources = resources;
    this.pablo     = pablo;
}

@Override public Drawable getDrawable(final String source) {
    final BitmapDrawablePlaceHolder result = new BitmapDrawablePlaceHolder();

    new AsyncTask<Void, Void, Bitmap>() {

        @Override
        protected Bitmap doInBackground(final Void... meh) {
            try {
                return pablo.load(source).get();
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(final Bitmap bitmap) {
            try {
                final BitmapDrawable drawable = new BitmapDrawable(resources, bitmap);

                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

                result.setDrawable(drawable);
                result.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

                textView.setText(textView.getText()); // invalidate() doesn't work correctly...
            } catch (Exception e) {
                /* nom nom nom*/
            }
        }

    }.execute((Void) null);

    return result;
}

static class BitmapDrawablePlaceHolder extends BitmapDrawable {

    protected Drawable drawable;

    @Override
    public void draw(final Canvas canvas) {
        if (drawable != null) {
            drawable.draw(canvas);
        }
    }

    public void setDrawable(Drawable drawable) {
        this.drawable = drawable;
    }

}

Hope this is useful.

Ufkoku

I built upon Thomas' answer. I used the existing Picasso methods to download any images on a different thread and accounted for the placeholder Drawables as well.

public class PicassoImageGetter implements Html.ImageGetter {
    private TextView textView = null;

    public PicassoImageGetter() {}

    public PicassoImageGetter(TextView target) {
        textView = target;
    }

    @Override
    public Drawable getDrawable(String source) {
        BitmapDrawablePlaceHolder drawable = new BitmapDrawablePlaceHolder();

        Context context = FeedSurferApp.getContext();
        FeedSurferApp
                .getPicasso()
                .load(source)
                .error(ResourcesCompat.getDrawable(context.getResources(), R.drawable.connection_error, context.getTheme()))
                .into(drawable);

        return drawable;
    }

    private class BitmapDrawablePlaceHolder extends BitmapDrawable implements Target {
        protected Drawable drawable;

        @Override
        public void draw(final Canvas canvas) {
            if (drawable != null) {
                drawable.draw(canvas);
            }
        }

        public void setDrawable(Drawable drawable) {
            this.drawable = drawable;
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            if (textView != null) {
                textView.setText(textView.getText());
            }
        }

        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            setDrawable(new BitmapDrawable(FeedSurferApp.getContext().getResources(), bitmap));
        }

        @Override
        public void onBitmapFailed(Drawable errorDrawable) {
            setDrawable(errorDrawable);
        }

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

I found a way to use ImageGetter with Picasso Target:

    public Drawable getDrawable(String source) {

            final BitmapDrawablePlaceHolder result = new BitmapDrawablePlaceHolder();

            Picasso.with(getContext()).load(source).into(new Target() {
                @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    final BitmapDrawable drawable = new BitmapDrawable(mContext.getResources(), bitmap);

                    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());


                    result.setDrawable(drawable);
                    result.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

                    content.setText(content.getText());




                    // cache is now warmed up
                }
                @Override public void onBitmapFailed(Drawable errorDrawable) { }
                @Override public void onPrepareLoad(Drawable placeHolderDrawable) { }
            });
            return result;

}

This uses the cache and is no longer a synchronous call requiring the AsyncTask.

Credit to: Fetch images with Callback in Picasso?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!