はじめに
キーボードの真上にViewを描画する際、キーボードの高さ計算を行うことがあると思いますが、
ノッチ端末で高さの取れ方が変わっていたので、記事に残しておきます。
従来のコード
従来の方法では、キーボードの高さを以下のように取得していました。
※フルスクリーン画面でのみTopを考慮しなくても動きます
// CustomView
val customViewAboveKeyboard: View
// キーボードの高さが変わった時に検知し、Viewの位置を調整する
viewTreeObserver.addOnGlobalLayoutListener {
val visibleHeight = getWindowVisibleDisplayHeight()
val selfHeight = customViewAboveKeyboard.height
customViewAboveKeyboard.y = (visibleHeight - selfHeight).toFloat()
}
fun getWindowVisibleDisplayHeight(): Int {
val rect = Rect()
val view = activity.window.decorView
view.getWindowVisibleDisplayFrame(rect)
return rect.bottom
}
しかしながら、上記の通りでは、ノッチの端末において高さが下にずれてしまいました。
これは、getWindowVisibleDisplayFrame()
関数で取得できる範囲がノッチバーの影響を受けて、rect.top
の値にノッチの高さが追加されるためです。
フルスクリーンの場合は、今までナビゲーションバーがなかったところに、ノッチバー分の高さが追加されるので、その分ずれます
なので、以下のようにtopの座標を考慮すると、正常に動くようになります。
変更後のコード
fun getWindowVisibleDisplayHeight(): Int {
val rect = Rect()
val view = activity.window.decorView
view.getWindowVisibleDisplayFrame(rect)
return rect.height() // ★ここでtopの座標も考慮し、height()を使う
}
最後に
余談ですが、キーボード上にViewを配置する方法としては、高さ計算をせずにandroid:windowSoftInputMode="adjustResize"
等を使ってViewの下端を上にずらしてしまう方法で実装することもできるかと思います。(こちらなど参考になります)
自身の担当するアプリケーションでは、View階層が複雑であったため、今回のような実装方法を用いております。
もっとうまい方法をご存知の方はご教授いただけますと助かります。
以上です。
追記
少し気になって検証を行った結果、元々フルスクリーンでない画面で実装する場合にはtopを考慮に入れないと位置がずれることがわかりました。
自分の担当するアプリケーションでは、フルスクリーンの画面でしか実装していなかったので、気づかなかったです、、、すいません。
いずれにせよ、キーボードの高さ計算等する場合には、ナビゲーションバーやノッチの高さに注意しながら実装する必要がありました。気をつけましょう。
尚、本格的にノッチバーの切り抜きに対応するためには、ThemeにLAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
などを適用する必要があるみたいです。
- Support display cutouts | Android Developers
-
Making Notch-Friendly Apps For Android…
後日、こちらも検証できたら、まとめてみようと思います。