AndroidアプリでWebViewを使っていると、リンクにtarget="_blank"
がついている場合、外部ブラウザが開いてしまうことがあります。今回は、アプリ内で新しいウィンドウ的に開く方法を紹介します。
問題点
通常のWebViewではtarget="_blank"
リンクをタップすると外部ブラウザに飛んでしまいます。アプリ内で完結させたい場合、この挙動を制御する必要があります。
解決方法
解決のポイントはWebViewClient
とWebChromeClient
を組み合わせることです。新しいウィンドウのリクエストをキャッチして、新しいWebViewを生成します。
コード例(Kotlin)
class CustomWebViewActivity : AppCompatActivity() {
private lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
webView = WebView(this)
setContentView(webView)
with(webView) {
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
webViewClient = WebViewClient()
webChromeClient = object : WebChromeClient() {
override fun onCreateWindow(
view: WebView?,
isDialog: Boolean,
isUserGesture: Boolean,
resultMsg: Message?
): Boolean {
val newWebView = WebView(this@CustomWebViewActivity)
newWebView.settings.javaScriptEnabled = true
newWebView.webViewClient = WebViewClient()
// 新しいWebViewをダイアログ等に表示する場合はここでセット
(resultMsg?.obj as? WebView.WebViewTransport)?.webView = newWebView
resultMsg?.sendToTarget()
return true
}
}
loadUrl("https://example.com")
}
}
}
補足
この方法を使えば、ターゲットブランクリンクもアプリ内で完結して表示可能です。なお、必要に応じてCookieやRefererの設定も追加すると、ログイン済みの状態を維持できます。
まとめ
- WebViewで
target="_blank"
を扱う場合はWebChromeClient
で新規ウィンドウを処理する - 新しいWebViewを生成してアプリ内で開くことでUXを改善できる
- 必要に応じてCookieやRefererを設定してログイン状態を維持する
この実装パターンを押さえておけば、SNS認証や外部リンクもアプリ内で安全に表示できます。
コメント