Flutter基于Riverpod实现主题切换

零 Flutter教程评论120字数 2951阅读9分50秒阅读模式

Flutter基于Riverpod实现主题切换

使用Riverpod来切换主题,主要的步骤是创建一个主题提供者,然后在应用中使用它来动态切换主题。文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17214.html

1. 创建一个主题提供者

dart

代码解读
复制代码
 final themeProvider = StateNotifierProvider<ThemeNotifier, ThemeMode>((ref) {
  return ThemeNotifier();
});

class ThemeNotifier extends StateNotifier<ThemeMode> {
  ThemeNotifier() : super(ThemeMode.light);

  void toggleTheme() {
    state = state == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
  }
}

2. 监听主题切换

dart

代码解读
复制代码
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(
    ProviderScope(
      child: MyApp(),
    ),
  );
}

class MyApp extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final themeMode = ref.watch(themeProvider);

    return MaterialApp(
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      themeMode: themeMode,
      home: HomePage(),
    );
  }
}

3. 触发主题切换

dart

代码解读
复制代码
class HomePage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      appBar: AppBar(title: Text(S.current.appName)),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                ref.read(themeProvider.notifier).toggleTheme();
              },
              child: Text('Theme Switch'),
            ),
          ],
        ),
      ),
    );
  }
}

到此,我们就可以实现一个主题的切换。但是我们有时候需要给不同主题下设置不同的特殊颜色,我们可以通过extends来扩写ThemeExtension。文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17214.html

dart

代码解读
复制代码
class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
  static const _colorB0B0B0 = Color(0xFFB0B0B0);

  static const _color6C6C6C = Color(0xFF6C6C6C);

  // 页面中真正使用到的颜色名称
  final Color backgroundDefault;
 

  // 私有的构造函数
  const AppColorsTheme._internal({
    required this.backgroundDefault,
  });

  // 浅色主题工厂方法
  factory AppColorsTheme.light() {
    return const AppColorsTheme._internal(
      backgroundDefault: _colorB0B0B0,
    );
  }

  // 暗色主题工厂方法
  factory AppColorsTheme.dark() {
    return const AppColorsTheme._internal(
      backgroundDefault: _color6C6C6C,
    );
  }

  @override
  ThemeExtension<AppColorsTheme> copyWith({bool? lightMode}) {
    if (lightMode == null || lightMode == true){
      return AppColorsTheme.light();
    }
    return AppColorsTheme.dark();
  }

  @override
  ThemeExtension<AppColorsTheme> lerp(
      covariant ThemeExtension<AppColorsTheme>? other, double t) => this;
}

然后使用extension ... on 来扩展ThemeData类,这样就可以便捷的访问自定义主题的属性文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17214.html

dart

代码解读
复制代码
extension ThemeDataExtension on ThemeData {
  AppColorsTheme get appColors => extension<AppColorsTheme>()!;
}

于是我们就需要对之前的代码作出适当的修改,比如我们设置HomePage页面的背景色为backgroundDefault。文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17214.html

  • 首先修改MyApp中的代码

dart

代码解读
复制代码
// myapp.dart
class MyApp extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final themeMode = ref.watch(themeProvider);

    return MaterialApp(
      theme: Theme.of(context).copyWith(extensions: [
        AppColorsTheme.light(),
      ]),
      darkTheme: Theme.of(context).copyWith(extensions: [
        AppColorsTheme.dark(),
      ]),
      themeMode: themeMode,
      home: HomePage(),
    );
  }
}

  • 修改HomePage中的代码

dart

代码解读
复制代码
class HomePage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      backgroundColor: Theme.of(context).appColors.backgroundDefault,
      appBar: AppBar(title: Text(S.current.appName)),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                ref.read(themeProvider.notifier).toggleTheme();
              },
              child: Text('Theme Switch'),
            ),
          ],
        ),
      ),
    );
  }
}

至此,我们就可以在AppColorsTheme中添加我们想要的自定义主题属性了。文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17214.html 文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17214.html

零
  • 转载请务必保留本文链接:https://www.0s52.com/bcjc/flutterjc/17214.html
    本社区资源仅供用于学习和交流,请勿用于商业用途
    未经允许不得进行转载/复制/分享

发表评论