LoginSignup
2
2

More than 5 years have passed since last update.

PicassoでWebView内の画像を設定する

Last updated at Posted at 2015-02-07

前回に引き続き、今回はWebView。

HTMLはローカル、画像はWebにある場合に、Picassoのメモリキャッシュを利用してオフラインでも画像を表示できる(かもしれない)。
ディスクキャッシュはオフラインでは利用できないため、利用したい場合はアプリ側で別途保持するなどの対応が必要。

Android4.3以前での注意点

以降は基本的にAndroid4.4以降向け。
Android4.3以前ではWebView#loadUrl()に渡す引数が長すぎるため、以下のエラーが発生してしまう。
Uncaught SyntaxError: Unexpected token ILLEGAL
Android4.3以前で同様の対応をするには、@kaaさんの[Android] native→webviewへ大きめのデータを渡すにあるように、分割して渡す必要がある。

assets内のHTML

画像を表示する要素(div)と画像を設定するJavascript(loadImage)があるだけ。

assets/index.html
<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript">
        function loadImage(id, mime, base64) {
            document.getElementById(id).innerHTML = "<img src='data:" + mime + ";base64," + base64 + "'/>";
        }
    </script>
</head>
    <body>
        <div id="image_area">
            <!-- ここに画像を表示 -->
        </div>
    </body>
</html>

Targetを実装したクラス

前回のActionBarアイコンを設定する方法同様、Targetを実装したクラスを作成する。
読み込み完了時にBase64エンコードして上記Javascriptを実行している。onPrepareLoadonBitmapFailedは省略。

WebViewTarget
public class WebViewTarget implements Target {

    private WebView mWebView;
    private String mId;

    public WebViewTarget(WebView webView, String id) {
        mWebView = webView;
        mId = id;
    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {
    }

    @Override
    public void onBitmapLoaded(Bitmap bitmap, LoadedFrom from) {
        String base64 = toBase64(bitmap);
        String js = String.format("javascript:loadImage('%s','%s','%s')", mId, "image/png", base64);
        mWebView.loadUrl(js);
    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {
    }

    private String toBase64(Bitmap bitmap) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        try {
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] bytes = stream.toByteArray();
            return Base64.encodeToString(bytes, Base64.DEFAULT);
        } finally {
            try {
                stream.close();
            } catch (IOException e) {
            }
        }
    }

呼び出し元

assets内のHTML読み込み完了後、Picassoで画像を読み込む。
メモリキャッシュがある場合は同期的に実行されるため、WebViewClient#onPageFinished以降に実行しないとUncaught ReferenceError: loadImage is not definedなどと怒られる。

MainActivity
final WebView webView = (WebView) findViewById(R.id.web);
webView.getSettings().setDefaultTextEncodingName("UTF-8");
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {

    private WebViewTarget mWebViewTarget = new WebViewTarget(webView, "image_area");

    @Override
    public void onPageFinished(WebView view, String url) {
        Picasso.with(MainActivity.this).load("<画像のURL>").into(mWebViewTarget);
    }
});
webView.loadUrl("file:///android_asset/index.html");

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2