はじめに
こんにちは、nobushiueshiです。
Android 17が正式リリースされたのでFlutterへの影響を確認していたところ、気になる変更を見つけました。
API 37を対象にしたアプリでは、大画面端末で画面の向き固定が効かなくなります。SystemChrome.setPreferredOrientationsを使うFlutterアプリは要注意なので、備忘録として残しておきます。
環境
- Flutter 3.44.0
- Dart 3.12
- Android 17(API 37)
Android 17で何が変わるのか
この挙動自体は、Android 16(API 36)でデフォルトとして導入されていました。ただし、Android 16ではマニフェストの設定で一時的にオプトアウトできました。
Android 17(API 37)で変わるのは、このオプトアウトが使えなくなる点です。API 37以上を対象にしたアプリを最小幅600dp以上の画面で動かすと、次のような指定が無視されます。
- 画面の向き固定
- ウィンドウのリサイズ制限
- アスペクト比の制限
Flutterの場合、影響するのが次のコードです。
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);つまり、縦固定のアプリでもAndroid 17のタブレットでは横向きで表示される可能性があります。最小幅600dp未満の画面は対象外です。
API 37を対象にする設定
android/app/build.gradle.ktsを利用している場合は、次のように設定します。
その前に、Android SDK Platform 37とAndroid SDK Build-Tools 37をインストールしておきます。Android Gradle Pluginは8.9.0-rc01以上が必要です。既存のFlutterプロジェクトでは古いバージョンが残っていることもあるので、先に確認しておいたほうがよさそうです。
android {
compileSdk = 37
defaultConfig {
targetSdk = 37
}
}前提となるSDKとAndroid Gradle Pluginを揃えた状態でAndroid 17のPixel Tabletエミュレーターを起動し、端末を回転させると影響を確認できます。
android:appCategory="game"が設定されたゲームアプリなど、一部には例外があるそうです。
大画面に対応する方法
今後は縦固定を前提にせず、利用できる横幅に応じてレイアウトを切り替える形にしておくのがよさそうです。
たとえばLayoutBuilderを使うと、600dpを境に縦並びと横並びを切り替えられます。
class SamplePage extends StatelessWidget {
const SamplePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: LayoutBuilder(
builder: (context, constraints) {
final children = <Widget>[
Expanded(
child: Container(
color: Colors.blue,
child: const Center(child: Text('メイン画面')),
),
),
Expanded(
child: Container(
color: Colors.orange,
child: const Center(child: Text('サブ画面')),
),
),
];
if (constraints.maxWidth >= 600) {
return Row(children: children);
}
return Column(children: children);
},
),
),
);
}
}これだけです。
実際のアプリでは、固定した向き以外でもレイアウトが崩れないか確認したほうがよさそうです。
さいごに
縦固定にしているからタブレットでも大丈夫だろう、と思っているとAPI 37への更新時にハマってしまいそうです。
Android 17対応の前に、一度大画面のエミュレーターで確認しておくと安心ですね。Flutterアプリを開発している方の参考になれば幸いです。
おすすめの書籍
参考





コメント