⌨️
【Tauri】Androidビルド時にUIがキーボードに隠れる問題
Webアプリをモバイル対応させる際,ソフトウェアキーボード(IME)の表示によってレイアウトが崩れる問題に直面することがあります.特に,ReactやTauriなどで構築したアプリをAndroid向けにビルドした際に,VisualViewportが思ったように動作しない問題に遭遇しました.
この記事では,その問題と解決策について共有します.
Visual Viewportが変化しない?
ReactなどのWebフロントエンドでは,ソフトウェアキーボードが表示されたときのレイアウト調整に window.visualViewport を使うのが一般的です.
ところが,AndroidにビルドしたTauriアプリでは,IMEが表示されても visualViewport.height が変化せず,UIがキーボードの裏に隠れてしまいました.
試したこと:adjustResizeの追加
調査したところ,同様の問題が GitHub でも報告されていました.
その中では,AndroidManifest.xml に以下のように windowSoftInputMode="adjustResize" を追加することで解決できるという報告もありました.
<application ... >
<activity
android:windowSoftInputMode="adjustResize" ... >
...
</activity>
...
</application>
しかし,私の環境では この方法ではうまく動作しませんでした.
解決した方法:MainActivity.ktでパディングを調整
最終的に効果があったのは,MainActivity.kt にて,IMEの表示に応じて paddingBottom を動的に設定する方法でした.
以下がそのコードです.
src-tauri/gen/android/app/src/main/java/com/[tauri_app]/app/MainActivity.kt
package com.[tauri_app].app
import android.os.Bundle
import androidx.core.view.WindowCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
class MainActivity : TauriActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { view, insets ->
val systemBarHeight = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom
val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
view.setPadding(
view.paddingLeft,
view.paddingTop,
view.paddingRight,
if (imeHeight > 0) imeHeight else systemBarHeight
)
insets
}
}
}
このコードは,システムバーとIMEのインセットを取得し,IMEが表示されているときはその高さ分だけ下に余白を追加するというものです.
おわり
-
VisualViewportは Android の WebView 上で正しく動作しないことがある -
adjustResizeを指定しても解決しないケースがある - Kotlin 側で
setOnApplyWindowInsetsListenerを使ってパディングを調整することで解決できる
Tauriで,Androidアプリを開発している方の参考になれば幸いです.
Discussion