WebView でピンチイン・ピンチアウトは有効にしたいけど、ズームボタンは邪魔。2014年の古い記事では廃止済み API が紹介されていた。2026年の正しい実装方法をまとめておく。
どちらのフレームワークを使うかで実装が異なる。
2026年:2つの実装パス
パス A:推奨Jetpack Compose を使う場合
@Composable
fun WebViewScreen() {
AndroidView(
factory = { context ->
WebView(context).apply {
settings.apply {
javaScriptEnabled = true
setSupportZoom(true)
setBuiltInZoomControls(true)
setDisplayZoomControls(false) // ← ズームボタン非表示
domStorageEnabled = true
databaseEnabled = true
}
webViewClient = WebViewClient()
}
},
modifier = Modifier.fillMaxSize(),
update = { webView ->
webView.loadUrl("https://example.com")
}
)
}
✅ メリット:
- 最新フレームワーク
- 状態管理が容易
- テストしやすい
パス B:レガシー従来の View 系を使う場合
ステップ 1:XML レイアウト
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
ステップ 2:Activity/Fragment で設定
class WebViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_webview)
val webview = findViewById<WebView>(R.id.webview)
val settings = webview.settings
// ピンチイン・ピンチアウトを有効
settings.setSupportZoom(true)
// ビルトインズームコントロールを有効
settings.setBuiltInZoomControls(true)
// ズームボタンを非表示 ← ここが重要
settings.setDisplayZoomControls(false)
webview.webViewClient = WebViewClient()
webview.loadUrl("https://example.com")
}
}
2014年の実装 vs 2026年の実装
| 項目 | 2014年 | 2026年 |
|---|---|---|
| フレームワーク | View(XML + Java) | Jetpack Compose(推奨)or View |
| API | setBuiltInZoomControls() |
同じ(廃止されていない) |
| 非表示方法 | リフレクション使用(廃止) | setDisplayZoomControls(false) |
| コード行数 | 5~10行 | Compose: 15行, View: 8行 |
| セキュリティ | 基本的 | WebViewClient で制御強化可能 |
| パフォーマンス | 標準 | Compose は仮想化対応 |
よくある落とし穴
1. setDisplayZoomControls() を設定し忘れ
❌ 悪い例:ズームボタンが表示される
settings.setSupportZoom(true)
settings.setBuiltInZoomControls(true)
// setDisplayZoomControls(false) がない!
✅ 正しい例:ズームボタンが非表示
settings.setSupportZoom(true)
settings.setBuiltInZoomControls(true)
settings.setDisplayZoomControls(false)
2. JavaScript が必要なサイトの場合
settings.apply {
javaScriptEnabled = true // ← 追加が必要な場合がある
setSupportZoom(true)
setBuiltInZoomControls(true)
setDisplayZoomControls(false)
}
3. セキュリティ設定を忘れずに
settings.apply {
// 安全でない HTTP を制限(Android 9+)
setSupportZoom(true)
setBuiltInZoomControls(true)
setDisplayZoomControls(false)
// 追加セキュリティ設定
mixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW
// ジオロケーション無効化
setGeolocationEnabled(false)
}
webview.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
// URL をフィルタリング
return false
}
}
API レベル別の対応
| API レベル | サポート | 対応方法 |
|---|---|---|
| API 11+ | ✅ | setDisplayZoomControls(false) 推奨 |
| API 19+ | ✅ | 同上 |
| API 21+ | ✅ | 同上 |
| API 29+ | ✅ | Jetpack Compose への移行を検討 |
実装チェックリスト
Jetpack Compose を使う場合
- ☑ AndroidView でWebView をラップ
- ☑ setSupportZoom(true)
- ☑ setBuiltInZoomControls(true)
- ☑ setDisplayZoomControls(false)
- ☑ WebViewClient を設定
- ☑ JavaScriptEnabled が必要か確認
- ☑ セキュリティ設定(mixedContentMode など)
View 系を使う場合
- ☑ WebView を XML レイアウトに配置
- ☑ findViewById で取得
- ☑ setSupportZoom(true)
- ☑ setBuiltInZoomControls(true)
- ☑ setDisplayZoomControls(false)
- ☑ WebViewClient を設定
- ☑ JavaScriptEnabled が必要か確認
- ☑ セキュリティ設定(mixedContentMode など)
2026年への移行:Compose 推奨理由
【従来の View 系】
- レガシーコード
- テストしづらい
- 状態管理が複雑
【Jetpack Compose】(推奨)
- モダンなフレームワーク
- テスト容易
- 状態管理が簡潔
- Android Studio の Compose Preview で動作確認可能
既に View 系で実装済みなら無理に移行は不要だが、新規プロジェクトなら Compose を検討する価値あり。