flutter开发实战-Theme主题切换

flutter开发实战-Theme主题切换

之前做的应用中有用到Theme主题切换,一直没有整理,这里整理一下。
使用的是Android studio

一、效果图

在这里插入图片描述

在这里插入图片描述

二、创建ThemeModel

// 提供五套可选主题色

const _themes = <MaterialColor>[
  Colors.blue,
  Colors.cyan,
  Colors.teal,
  Colors.green,
  Colors.red,
];

class Global {
    
    
  static late SharedPreferences _prefs;
  static Session session = Session();

  // 可选的主题列表
  static List<MaterialColor> get themes => _themes;

  // 是否为release版
  static bool get isRelease => bool.fromEnvironment("dart.vm.product");

  //初始化全局信息,会在APP启动时执行
  static Future init() async {
    
    
    WidgetsFlutterBinding.ensureInitialized();
    _prefs = await SharedPreferences.getInstance();
    var _profile = _prefs.getString("session");
    if (_profile != null) {
    
    
      try {
    
    
        session = Session.fromJson(jsonDecode(_profile));
      } catch (e) {
    
    
        LoggerManager().debug("e:${
      
      e.toString()}");
      }
    } else {
    
    
      // 默认主题索引为0,代表蓝色
      session = Session()..theme = 0;
    }
  }

  // 持久化Profile信息
  static saveProfile() {
    
    
    _prefs.setString("session", jsonEncode(session.toJson()));
  }
}
class Session {
    
    
  int? _theme;
}
// 共享状态
class SessionChangeNotifier with ChangeNotifier {
    
    
  Session get session => Global.session;

  String? get getToken => Global.session.token;

  
  void notifyListeners() {
    
    
    // 保存Profile变更
    Global.saveProfile();

    //通知依赖的Widget更新
    super.notifyListeners();
  }
}
class ThemeModel extends SessionChangeNotifier {
    
    
  // 获取当前主题,如果为设置主题,则默认使用蓝色主题
  MaterialColor get theme => Global.themes
      .firstWhere((e) => e.value == session.theme, orElse: () => Colors.blue);

  // 主题改变后,通知其依赖项,新主题会立即生效
  set theme(MaterialColor color) {
    
    
    if (color != theme) {
    
    
      session.theme = color[500]?.value;
      notifyListeners();
    }
  }
}

在Main.dart入口的MaterialApp

MaterialApp(
      theme: ThemeData(
        fontFamily: "PingFang SC",
        primarySwatch: themeModel.theme,
      ),
 ...

三、主题切换页面

当主题切换后,Provider会通知到对应的页面Build,就会显示对应的主题。

主题切换页面

class ThemePage extends StatefulWidget {
    
    
  const ThemePage({
    
    Key? key, this.arguments}) : super(key: key);

  final Object? arguments;

  
  State<ThemePage> createState() => _ThemePageState();
}

class _ThemePageState extends State<ThemePage> {
    
    
  
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      appBar: MyAppBar(
        onPressed: () {
    
    
          navigatorBack();
        },
        label: S.of(context).theme,
        isBackButton: true,
      ),
      body: ListView(
        //显示主题色块
        children: Global.themes.map<Widget>((e) {
    
    
          return GestureDetector(
            child: Padding(
              padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 16),
              child: Container(
                color: e,
                height: 40,
              ),
            ),
            onTap: () {
    
    
              //主题更新后,MaterialApp会重新build
              Provider.of<ThemeModel>(context, listen: false).theme = e;
            },
          );
        }).toList(),
      ),
    );
  }

  void navigatorBack() {
    
    
    NavigatorPageRouter.pop();
  }
}

四、小结

flutter开发实战-Theme主题切换,使用的是Android studio,使用Provider通知切换主题。

学习记录,每天不停进步。

猜你喜欢

转载自blog.csdn.net/gloryFlow/article/details/131638632