webviewに半年ほど消耗してるので、カッとなって書いた。
今まで十数回と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をそのまま表示するよりはだいぶマシなので、こちらも良ければお使いください。
(左 ローディング画面 右 エラー画面 )