これ以上CustomWebViewで消耗しないためのAndroid用ライブラリ

webviewに半年ほど消耗してるので、カッとなって書いた。

github.com

今まで十数回とWebViewを継承したクラスを作ってきました。
ネイティブアプリでも利用規約やライセンスの表示などは必ずと言っていいほどWebViewを利用します。

残念なことに、AndroidのWebViewはちょっと使いづらいです。
そこでWebView継承したカスタムWebViewを毎回用意するのですが、いつも同じこと書いてるので、少し抽象化して汎用的な便利WebViewをライブラリとして公開しました。

LxWebViewの特徴を簡単に紹介します。

XMLでWebViewSettingsを設定

WebViewSettingsは毎回コードから設定していましたが、XML attributesから記述できるようにしました。

    <com.kazy.lx.LxWebView
            android:id="@+id/webview_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            lx:dom_storage_enabled="true"
            lx:app_cache_enabled="true"
            lx:java_script_enabled="true"
            lx:built_in_zoom_controls="true"
            lx:display_zoom_controls="false"
            lx:load_with_overview_mode="true"
            lx:use_wide_view_port="true"/>

View切り替え用のListener

エラービューの表示や読み込み状況の取得は、やや煩雑なコードが必要でしたが、一つのInterfaceにまとめました。

lxWebView.addOnWebViewStateListener(new WebViewStateListener() {
    @Override
    public void onStartLoading(String url, Bitmap favicon) {
    }

    @Override
    public void onError(int errorCode, String description, String failingUrl) {
    }

    @Override
    public void onFinishLoaded(String loadedUrl) {
    }

    @Override
    public void onProgressChanged(WebView view, int progress) {
    }
});

onFinishLoadedはWebViewClient#onFinishLoadedと異なり、エラー時には呼ばれません。 正常にページが読み込まれた際にのみ行いたい処理を、onFinishLoadedに記述します。

ページ読み込みに対する割り込み処理

特定URLをフックして何か処理をするために、LoadingInterceptorというInterfaceが用意されています。(Playストアを開く, 電話インテントを呼ぶ etc)
例えばhttpとhttps以外のプロトコルのURLを読み込む場合、外部に暗黙的インテントを発行するコードはこのようになります。

public class RootActivity extends ActionBarActivity {

    @InjectView(R.id.webview_view)
    LxWebView lxWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_root);
        lxWebView.addLoadingInterceptor(new UnsupportedProtcolInterceptor(this));
    }

    private class UnsupportedProtcolInterceptor implements LoadingInterceptor {

        private Activity activity;

        public UnsupportedProtcolInterceptor(Activity activity) {
            this.activity = activity;
        }

        @Override
        public boolean validate(Uri uri) {
            return !uri.getScheme().equals("http") && !uri.getScheme().equals("https");
        }

        @Override
        public void exec(Uri uri) {
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            activity.startActivity(intent);
        }
    }
}

以上がLxWebViewの特徴です。 よければぜひ使って下さい。

さらに、楽をするためのWebView

実はLxWebviewの中にLxContainerWebViewというクラスを用意しています。
これを使うとエラー表示と画面上部のローディングバーが表示されるwebviewが何もしなくても利用できます。

使い方は、

Step 1. jitpack.ioのレポジトリを追加して
  repositories {
    maven {
      url "https://jitpack.io"
    }
  }
Step 2.dependenciesにLxWebViewを追加
  dependencies {
    compile 'com.github.kazy1991:LxWebView:0.1.1'
  }
Step 3. WebViewの代わりにLxWebContainerViewを指定
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:lx="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <com.kazy.lx.LxWebContainerView
            android:id="@+id/webview_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            lx:dom_storage_enabled="true"
            lx:app_cache_enabled="true"
            lx:java_script_enabled="true"
            lx:built_in_zoom_controls="true"
            lx:display_zoom_controls="false"
            lx:load_with_overview_mode="true"
            lx:use_wide_view_port="true"/>
</RelativeLayout>

生のWebviewをそのまま表示するよりはだいぶマシなので、こちらも良ければお使いください。

(左 ローディング画面 右 エラー画面 )