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:
parent
9b8946be49
commit
cd86d34d5a
4 changed files with 26 additions and 4 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tokilabs.mattermost
|
package com.tokilabs.mattermost
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
import com.tokilabs.mattermost.helpers.DatabaseHelper
|
import com.tokilabs.mattermost.helpers.DatabaseHelper
|
||||||
import com.tokilabs.mattermost.helpers.Network
|
import com.tokilabs.mattermost.helpers.Network
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
@ -100,6 +101,8 @@ class MainActivity : FlutterActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
|
||||||
// 알림 탭으로 앱 진입 시 Intent 데이터를 Flutter로 전달
|
// 알림 탭으로 앱 진입 시 Intent 데이터를 Flutter로 전달
|
||||||
intent?.extras?.let { extras ->
|
intent?.extras?.let { extras ->
|
||||||
val data = mutableMapOf<String, Any?>()
|
val data = mutableMapOf<String, Any?>()
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
<!-- Show a splash screen on the activity. Automatically removed when
|
<!-- Show a splash screen on the activity. Automatically removed when
|
||||||
the Flutter engine draws its first frame -->
|
the Flutter engine draws its first frame -->
|
||||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
<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>
|
</style>
|
||||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
This theme determines the color of the Android Window while your
|
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. -->
|
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||||
<item name="android:windowBackground">?android:colorBackground</item>
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
<!-- Show a splash screen on the activity. Automatically removed when
|
<!-- Show a splash screen on the activity. Automatically removed when
|
||||||
the Flutter engine draws its first frame -->
|
the Flutter engine draws its first frame -->
|
||||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
<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>
|
</style>
|
||||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
This theme determines the color of the Android Window while your
|
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. -->
|
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||||
<item name="android:windowBackground">?android:colorBackground</item>
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'services/mattermost_auth_service.dart';
|
import 'services/mattermost_auth_service.dart';
|
||||||
import 'services/push_notification_background.dart';
|
import 'services/push_notification_background.dart';
|
||||||
|
|
@ -9,9 +10,20 @@ import 'services/push_notification_service.dart';
|
||||||
final _navigatorKey = GlobalKey<NavigatorState>();
|
final _navigatorKey = GlobalKey<NavigatorState>();
|
||||||
final _pushService = PushNotificationService();
|
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 {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
await _applyFullscreenMode();
|
||||||
|
|
||||||
await Firebase.initializeApp();
|
await Firebase.initializeApp();
|
||||||
|
|
||||||
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
|
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
|
||||||
|
|
@ -68,6 +80,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
_applyFullscreenMode();
|
||||||
|
});
|
||||||
_notifSub = _pushService.onNotification.listen((data) {
|
_notifSub = _pushService.onNotification.listen((data) {
|
||||||
if (data['type'] != 'message') return;
|
if (data['type'] != 'message') return;
|
||||||
final message = data['message'] as String? ?? '';
|
final message = data['message'] as String? ?? '';
|
||||||
|
|
@ -97,10 +112,6 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
|
||||||
title: Text(widget.title),
|
|
||||||
),
|
|
||||||
body: const Center(
|
body: const Center(
|
||||||
child: Text('NomadCode'),
|
child: Text('NomadCode'),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue