谈谈Flutter适配深色模式

一、前言
现在app适配深色模式都是主流了,也因为项目刚开始,所以打算一开始就把深色模式考虑进去,不一定要用,但至少要留好口子,以便以后来了个需求,就会各种繁琐,各种判断之类的。所以就有了全局深色模式的尝试。以下的实现是我自己的看法和设计。如有不合之处,请指出!谢谢!

二、需求
因为颜色是统一配置的,所以我只想简单的一个颜色类调用定义的颜色就达到颜色适配的效果。不想在组件设置颜色的地方来判断是否是深色模式,然后设置对应颜色,这样会特别繁琐,也怕有遗漏的地方。后期维护的时候也特别麻烦。当然flutter本来就有很多主题设置,可以设置组件的是否什么颜色,但是总有地方还需要自己来适配的。所以我就做了一个这样的方案。

先看效果:
在这里插入图片描述

在这里插入图片描述

三、具体实现(这边使用GetX来实现切换深色模式,也可以用其他设置,但颜色类是这样的。不管用什么方式都可以。)

1、创建一个颜色类:

class FXColor {
  /// 主色
  static get mainBg {
    return FXColorConfig.getColor(FXColorConfig.main_bg_key);
  }
}

2、外部调用

appBar: AppBarWidget(
        '首页详情',
        context: context,
        backgroundColor: FXColor.mainBg, // 就这样调用 这样既可
        titleColor: FXColor.title,
      ),

三、具体实现

/// 颜色类适配黑暗模式 三步骤 1 2 3 ,一般来说一个app的样式,不会太多,所以这边处理就可以达到全局设置。
/// 适配黑暗模式步骤 添加之前可先查看是否已经添加该样式
/// 1 FXColorConfig类中添加颜色key, 例 static const String main_bg_key = 'main_bg';
/// 2 FXColorConfig类中的_colors集合中添加颜色key-value
///   例:main_bg_key: [FXColor.whiteColor, FXColor.colorText33],
///   key:main_bg_key是步骤1添加的key, value:数组 两个颜色值,0是正常模式颜色,1是黑暗模式颜色
/// 3 FXColor类添加get方法 对外访问
///   例 static get mainBg {
//        return FXColorConfig.getColor(FXColorConfig.main_bg_key);
//       }

FXColorConfig类和FXColor类的全部实现

//对外调用
class FXColor {
  /// 主色
  static get mainBg {
    return FXColorConfig.getColor(FXColorConfig.main_bg_key);
  }

  /// title 标题
  static get title {
    return FXColorConfig.getColor(FXColorConfig.title_key);
  }

  /// subTitle 副标题
  static get subTitle {
    return FXColorConfig.getColor(FXColorConfig.sub_title_key);
  }

  /// content 内容
  static get content {
    return FXColorConfig.getColor(FXColorConfig.content_key);
  }

  /// buttonBg 按钮背景
  static get buttonBg {
    return FXColorConfig.getColor(FXColorConfig.button_bg_key);
  }

  /// buttonTitle 按钮标题
  static get buttonTitle {
    return FXColorConfig.getColor(FXColorConfig.button_title_key);
  }

  /// buttonTitle 按钮标题
  static get divider {
    return FXColorConfig.getColor(FXColorConfig.divider_key);
  }

///常用颜色值
  /// 透明
  static const Color colorTransparent = Colors.transparent;

  /// 主视图背景色
  static Color colorBackground =
      Get.isDarkMode ? Color(0xFFFFFFFF) : Color(0xFF2268F2);

  ///导航栏背景颜色
  static const Color color_nav_bar_bg = Color(0xFFFFFFFF);

  ///主要 分割线
  static const Color color_divider = Color(0xFFEDEDED);

  /// 进度颜色
  static const Color color_progress = Color(0xFFE6E7E9);

  /// 文本颜色
  static const Color color_text_33 = Color(0xFF333333);

  /// 文本颜色
  static const Color color_text_66 = Color(0xFFE6E7E9);

  /// 文本颜色
  static const Color color_text_99 = Color(0xFF999999);

  /// 文本颜色
  static const Color color_text_hint = Color(0xFFE6E7E9);

  /// 红色
  static const Color red_color = Color(0xFFFF3622);

  ///蓝色
  static const Color blue_color = Color(0xFF2268F2);

  ///白色
  static const Color white_color = Color(0xFFFFFFFF);

  /// 黑色
  static const Color black_color = Color(0xFF000000);

  ///绿色
  static const Color green_color = Color(0xFF06C88C);

  ///黄色
  static const Color yellow_color = Color(0xFFF5A623);
}
/// 颜色配置 
class FXColorConfig {
  /// 颜色key
  static const String main_bg_key = 'main_bg';
  static const String title_key = 'title';
  static const String sub_title_key = 'sub_title';
  static const String content_key = 'content';
  static const String button_bg_key = 'button_bg';
  static const String button_title_key = 'button_title';
  static const String divider_key = 'divider';

  /// 颜色值
  static const _colors = {
    main_bg_key: [FXColor.white_color, FXColor.color_text_33],
    title_key: [FXColor.color_text_33, FXColor.white_color],
    sub_title_key: [FXColor.color_text_33, FXColor.white_color],
    content_key: [FXColor.color_text_33, FXColor.white_color],
    button_bg_key: [FXColor.red_color, FXColor.yellow_color],
    button_title_key: [FXColor.color_text_33, FXColor.white_color],
    divider_key: [FXColor.color_text_33, FXColor.white_color],
  };

  /// 取颜色值
  static Color getColor(String key) {
    final colors = _colors[key];
    if (colors == null) {
      return FXColor.color_text_33;
    }

    if (Get.isDarkMode == true) {
      if (colors.length == 2) {
        return colors[1];
      } else {
        return colors[0];
      }
    } else {
      return colors[0];
    }
  }
}

最后创建一个设置是否深色模式的类 ThemeConfig

///主题色配置 统一配置
class ThemeConfig {
  /// 正常模式主题设置
  static ThemeData lightTheme = ThemeData(brightness: Brightness.light);

  /// 黑暗模式主题设置
  static ThemeData darkTheme = ThemeData(brightness: Brightness.dark);

  ///设置黑暗模式
  static void changeThemeMode({ThemeMode themeMode = ThemeMode.system}) {
    /// 主题类型
    Get.changeThemeMode(themeMode);

    /// 注意样式设置
//    switch (themeMode) {
//      case ThemeMode.system:
//        if (Get.isDarkMode == true) {
//          Get.changeTheme(darkTheme);
//        } else {
//          Get.changeTheme(lightTheme);
//        }
//        break;
//      case ThemeMode.dark:
//        Get.changeTheme(darkTheme);
//        break;
//      case ThemeMode.light:
//        Get.changeTheme(lightTheme);
//        break;
//    }
  }
}

调用:

/// 正常模式
ThemeConfig.changeThemeMode(themeMode: ThemeMode.light);

/// 深色模式
ThemeConfig.changeThemeMode(themeMode: ThemeMode.dark);

四、后续
深色模式就以上的全部实现,对此多语言设置应该也可以同样的思路来解决。后续会继续写个多语言适配。

记录代码,记录生活…

最后demo地址: https://github.com/yj229201093/darkmode

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

建古

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值