feat(android): Implement immersive mode for Flutter app

- Enable Flutter view to render behind system UI (status bar, navigation bar)
- Set transparent status bar and navigation bar colors in styles.xml
- Enable immersive sticky mode in Flutter main.dart
- MainActivity.kt: Set decor fits system windows to false for full-screen layout
This commit is contained in:
toki 2026-03-22 22:51:58 +09:00
parent 9b8946be49
commit cd86d34d5a
4 changed files with 26 additions and 4 deletions

View file

@ -1,6 +1,7 @@
package com.tokilabs.mattermost
import android.os.Bundle
import androidx.core.view.WindowCompat
import com.tokilabs.mattermost.helpers.DatabaseHelper
import com.tokilabs.mattermost.helpers.Network
import io.flutter.embedding.android.FlutterActivity
@ -100,6 +101,8 @@ class MainActivity : FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
// 알림 탭으로 앱 진입 시 Intent 데이터를 Flutter로 전달
intent?.extras?.let { extras ->
val data = mutableMapOf<String, Any?>()

View file

@ -5,6 +5,8 @@
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
@ -14,5 +16,7 @@
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
</resources>

View file

@ -5,6 +5,8 @@
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
@ -14,5 +16,7 @@
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
</resources>

View file

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'services/mattermost_auth_service.dart';
import 'services/push_notification_background.dart';
@ -9,9 +10,20 @@ import 'services/push_notification_service.dart';
final _navigatorKey = GlobalKey<NavigatorState>();
final _pushService = PushNotificationService();
Future<void> _applyFullscreenMode() async {
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
systemNavigationBarColor: Colors.transparent,
systemNavigationBarDividerColor: Colors.transparent,
));
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await _applyFullscreenMode();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
@ -68,6 +80,9 @@ class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_applyFullscreenMode();
});
_notifSub = _pushService.onNotification.listen((data) {
if (data['type'] != 'message') return;
final message = data['message'] as String? ?? '';
@ -97,10 +112,6 @@ class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: const Center(
child: Text('NomadCode'),
),