Android 15からedge-to-edgeがデフォルトで適用されるので挙動を確認してみた

## はじめに

Android15 から `edge-to-edge` がデフォルトになり、意図しない挙動になっていないかの確認を行ってみました。
確認は、弊社で公開している [家計簿](https://play.google.com/store/apps/details?id=jp.co.tanocee.kakeibo.android&utm_source=qiita&utm_campaign=android15_edgetoedge) アプリで行いました。

https://play.google.com/store/apps/details?id=jp.co.tanocee.kakeibo.android&utm_source=qiita&utm_campaign=android15_edgetoedge

## 変更内容の確認

変更点としては、以下になります。

- `targetSdk` を `35` に変更すると `edge-to-edge` が Android15 で対応していないアプリでも適用されること
- [M3](https://m3.material.io/) を適用している場合、自動的に `Insets` を適用するため、特段対応が不要であること
- [M2](https://m2.material.io/) を適用している & `edge-to-edge` 対応していない場合、自動的に `Insets` が適用されないため、手動での対応が必要であること

## 実際に動かしたときの確認

家計簿 は、M3 を適用してアプリを作成しているため、自動で適用されるはずですが、確認していきます。
確認は、以下 OS のエミュレーターで行いました。

- Android14
- Android15

### targetSdk 34 で動かしたとき

| Android14 | Android15 |
| --- | --- |
|![Screenshot_20240625_014121.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501749/9288a06d-3789-00b3-2664-64e07540ca58.png)|![Screenshot_20240625_013917.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501749/c8b4bf9a-cb97-7a75-8e6a-ae1e24140826.png)|

targetSdk を上げていないため、挙動に差異はありませんでした。

※ StatusBar の大きさに違いはありますが、これは 実機の Android15 では発生していないため、エミュレーターの問題です。

### targetSdk 35 で動かしたとき

| Android14 | Android15 |
| --- | --- |
|![Screenshot_20240625_013205.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501749/3cca3e4c-5626-2d88-cb21-31acaffd811a.png)|![Screenshot_20240625_013317.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501749/302906bb-d843-bc27-89e3-d936f7f72d22.png)|

`M3` を適用しているため、対応不要で `edge-to-edge` が適用されていました。

ただし、Android15 で以下の気になるところがありました。

- `BottomSheet` が `Navigation bar` の領域分下がるため、閉じた後に開くことがしづらい
- `adjustResize` を設定しているにも関わらず、ソフトウェアキーボードでアプリの内容が隠れる

これは対応が必要のため、次のセクションで説明します。

- `Status Bar` の情報が白地に白文字でライトモード時に見えなくなっている

これは、 OS 上の問題なのかもしれませんので、もう少し待ってみます。

## BottomSheetが下がることソフトウェアキーボード内にアプリ内容が隠れることについて

> If your app is using views and BottomSheet, SideSheet or custom containers, apply padding using ViewCompat.setOnApplyWindowInsetsListener. For RecyclerView, apply padding using this listener and also add clipToPadding="false".

上記から、`WindowInset` が自動で適用されない模様で、 Compose では以下を追加して対応します。

※ ドキュメントを閲覧した限り、そのように解釈しましたが、もし異なっていましたらコメント等でご指摘ください。

``` kotlin
Box(
  modifier = modifier = Modifier.safeDrawingPadding(),
  ...
) {
```

[safeDrawingPadding](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.ui.Modifier).safeDrawingPadding()) は、ステータスバー、ナビゲーションバー、IMEのスペース分、適用されます。

変更したところ以下のように対応できました。

### 閉じているときの BottomSheet

|対応前|対応後|
| --- | --- |
|![Screenshot_20240625_014435.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501749/21a17e80-cfcf-4b70-1aad-4eb4322a1bbe.png)|![Screenshot_20240625_012646_collasped.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501749/d007ad89-8311-c4e3-a55d-22e90171ae81.png)|

### ソフトウェアキーボード

|対応前|対応後|
| --- | --- |
|![Screenshot_20240624_010912.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501749/54ee86e8-7e8e-fb7e-ee57-95fc2f04ed16.png)|![Screenshot_20240625_012709_keyboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501749/edd1b265-8f3a-d141-c113-caca2af058e3.png)|

## まとめ

今回確認したアプリでは、 `M3` を使用していたため、特段大きな変更がないため、修正工数もほとんどかからないことがわかりました。
ですが、 `M2` を使用している場合は、手動で `Insets` を適用する必要があるため、一度 `targetSdk` を上げてみると良いかと思います。
特に大規模なアプリの場合は、対応に工数がかかると思いますので、早めに確認した方が良さそうです。

## 参考

- [Android15](https://developer.android.com/about/versions/15)
- [Android15 - User experience and system UI](https://developer.android.com/about/versions/15/behavior-changes-15)
- [Material Design 3](https://m3.material.io/)
- [Material Design 2](https://m2.material.io/)