Loading

Flutter 底部(手势条)和顶部导航栏沉浸适配多主题

适配原理

顶部导航栏和状态栏沉浸实现比较简单,设置Scaffold的AppBar背景色即可,其中surfaceTintColor可以设置IOS滑动之后状态栏颜色,不想要显示顶部导航栏高度设置toolbarHeight:0,阴影设置elevation: 0

@override
Widget build(BuildContext context) {
  var bg = Theme.of(context).colorScheme.surface;
  return Scaffold(
    appBar: AppBar(
      elevation: 0,
      toolbarHeight: 0,
      backgroundColor: bg,
      surfaceTintColor: bg,
    ),
    backgroundColor: bg,
  )
}

底部导航栏即手势条,也叫小白条。IOS不需要特别适配,设置colorSchemesurface背景即可。

ThemeData lightMode = ThemeData(
  useMaterial3: true,
  colorScheme: const ColorScheme.light(
    surface: Color.fromARGB(255, 242, 247, 251),
  ),
);

适配代码

Android底部手势条需要特别适配,下面的代码同样适用于IOS

亮色主题

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

ThemeData lightMode = ThemeData(
  useMaterial3: true,
  // 沉浸的关键代码
  appBarTheme: const AppBarTheme(
    systemOverlayStyle: SystemUiOverlayStyle(
      statusBarColor: Colors.transparent, // 去除状态栏遮罩
      statusBarIconBrightness: Brightness.dark, // 状态栏图标字体颜色
      systemNavigationBarColor: Color.fromARGB(255, 242, 247, 251), // 底部导航栏颜色
    )
  ),
  colorScheme: const ColorScheme.light(
    surface: Color.fromARGB(255, 242, 247, 251), // 和底部导航栏保持一致
    surfaceBright: Color(0x00FFFFFF), // 透明背景
    primary: Color.fromARGB(255, 89, 54, 133),
    secondary: Color(0xFFE3EDF2),
    tertiary: Colors.black,
    onSecondary: Colors.black,
    secondaryContainer: Color(0xFFE3EDF2), // 骨架屏底色
    onSecondaryContainer: Color.fromARGB(255, 242, 247, 251), // 骨架屏亮色
    inversePrimary: Colors.black54,
  ),
);

暗色主题

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

ThemeData darkMode = ThemeData(
  useMaterial3: true,
  // 沉浸的关键代码
  appBarTheme: const AppBarTheme(
    systemOverlayStyle: SystemUiOverlayStyle(
      statusBarColor: Colors.transparent,
      statusBarIconBrightness: Brightness.light,
      systemNavigationBarColor: Color(0xFF121012),  // 和主背景surface保持一致
    )
  ),
  colorScheme: const ColorScheme.dark(
    surface: Color(0xFF121012), 
    surfaceBright: Color(0x00000000), // 透明背景
    primary: Color.fromARGB(255, 89, 54, 133),
    secondary: Color(0xFF382C3E),
    tertiary: Colors.white,
    onSecondary: Colors.white30, // 骨架屏底色
    secondaryContainer: Color.fromARGB(255, 12, 11, 12), // 骨架屏亮色
    onSecondaryContainer: Colors.black26,
    inversePrimary: Colors.white54,
  ),
);

使用Provider

你需要安装 provider

flutter pub add provider

动态切换代码

import 'package:flutter/material.dart';
import 'package:video_app/theme/dark_theme.dart';
import 'package:video_app/theme/light_theme.dart';

class ThemeProvider extends ChangeNotifier {
  ThemeData _themeData = lightMode;

  ThemeData get themeData => _themeData;

  ThemeData get darkTheme => darkMode;
  ThemeData get lightTheme => lightMode;

  set themeData(ThemeData themeData) {
    _themeData = themeData;
    notifyListeners();
  }

  void toggleTheme() {
    if (_themeData == lightMode) {
      themeData = darkMode;
    } else {
      themeData = lightMode;
    }
  }
}

主题设置

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
      designSize: designSize,
      builder: (context, child) {
        return MaterialApp(
          theme: Provider.of<ThemeProvider>(context).themeData, // 动态主题
          darkTheme: Provider.of<ThemeProvider>(context).darkTheme, // 暗色主题,设置后不能手动切换
          home: const RootScreen(),
          debugShowCheckedModeBanner: false,
        );
      },
    );
  }
}
posted @ 2024-07-16 13:29  sw-code  阅读(375)  评论(0编辑  收藏  举报