Flutter -黑夜/白天模式
1.简介
黑夜/白天模式,在App中非常常见,那么如何通过Flutter来修改主题了
2.Theme
theme: ThemeData(
brightness:
_isLight == true ? Brightness.light : Brightness.dark //判断 夜间/白天模式
),
————————通过控制ThemeData来实现主题的切换
代码
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'InWell.dart';
void main() {
runApp(ThemeView());
}
class ThemeView extends StatefulWidget {
ThemeView({Key key}) : super(key: key);
@override
_ThemeViewState createState() {
return _ThemeViewState();
}
}
class _ThemeViewState extends State<ThemeView> {
bool _isLight = true; //判断是否是夜间模式 true白天 false夜间
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
theme: ThemeData(
brightness:
_isLight == true ? Brightness.light : Brightness.dark //判断 夜间/白天模式
),
home: Scaffold(
appBar: AppBar(title: Text("flutter theme")),
body: Builder(
builder: (context) => Center(
child: Column(
children: <Widget>[
OutlinedButton(
onPressed: () {
setState(() {
_isLight == true ? _isLight = false : _isLight = true;
});
Navigator.push(context, MaterialPageRoute(
builder: (BuildContext context) {
return InkWellPage();
},
));
},
child: Text('改变主题'))
],
),
),
)),
);
}
}
3.通过Provider实现主题的切换
——————————一个顶级Provider,共所有组件使用,顺带切换
import 'package:flutter/material.dart';
import 'package:flutter_first/generated/l10n.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart';
import 'DarkModePage.dart';
import 'DarkModeProvider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: DarkProvider()),
],
child: Consumer<DarkProvider>(
builder: (context, darkModeProvider, _) {
return darkModeProvider.darkMode == 2
? MaterialApp(
// 设置语言
localizationsDelegates: const [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
// 讲zh设置为第一项,没有适配语言时,英语为首选项
supportedLocales: S.delegate.supportedLocales,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
darkTheme: ThemeData.dark(),
home: DarkPage(),
)
: MaterialApp(
// 设置语言
localizationsDelegates: const [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
// 讲zh设置为第一项,没有适配语言时,英语为首选项
supportedLocales: S.delegate.supportedLocales,
title: 'Flutter Demo',
theme: darkModeProvider.darkMode == 0
? ThemeData.dark()
: ThemeData(
primarySwatch: Colors.blue,
),
home: DarkPage(),
);
},
),
);
}
}
DarkPage
import 'package:flutter/material.dart';
import 'package:flutter_first/generated/l10n.dart';
import 'package:provider/provider.dart';
import 'DarkModeProvider.dart';
import 'HomeView.dart';
class DarkPage extends StatefulWidget {
@override
_DarkPageState createState() => _DarkPageState();
}
class _DarkPageState extends State<DarkPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ListView(
children: ListTile.divideTiles(context: context, tiles: [
ListTile(
title: Text('黑夜'),
onTap: () {
Provider.of<DarkProvider>(context, listen: false)
.changeMode(0);
},
),
ListTile(
title: Text('普通'),
onTap: () {
Provider.of<DarkProvider>(context, listen: false)
.changeMode(1);
},
),
ListTile(
title: Text('随系统'),
onTap: () {
Provider.of<DarkProvider>(context, listen: false)
.changeMode(2);
},
),
ListTile(
title: Text('跳转'),
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (BuildContext context) {
return HomeView();
},
));
},
)
]).toList(),
)));
}
}
DarkProvider
import 'package:flutter/material.dart';
class DarkProvider with ChangeNotifier {
/// 夜间模式 0: 关闭 1: 开启 2: 随系统
int _darkMode;
int get darkMode => _darkMode;
void changeMode(int darkMode) async {
_darkMode = darkMode;
notifyListeners();
}
}
————————个人感觉,provider监听Consumer还是比较复杂,而且全局刷新,我们来看一看Getx是如何做到的
4.通过Getx修改主题
onPress中,修改主题,但是GetMaterialController不具有更新的功能,所以需要搭配其他的GetXController,如果provider一致
Get.changeTheme(Get.isDarkMode? ThemeData.light(): ThemeData.dark());
代码如下:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'ThemeController.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final controller = Get.put(ThemeController());
MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetBuilder<ThemeController>(
builder: (ThemeController themeController) {
return GetMaterialApp(
theme: Get.find<ThemeController>().darkMode == 0
? ThemeData.light()
: ThemeData.dark(),
home: HomeGetxView(),
);
},
);
}
}
class HomeGetxView extends StatefulWidget {
HomeGetxView({Key key}) : super(key: key);
@override
_HomeGetxViewState createState() {
return _HomeGetxViewState();
}
}
class _HomeGetxViewState extends State<HomeGetxView> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Get主题测试')),
body: Column(
children: [
GetBuilder<ThemeController>(
builder: (ThemeController themeController) {
return Text("${Get.find<ThemeController>().darkMode}");
},
),
OutlinedButton(
onPressed: () {
Get.find<ThemeController>().changeMode(Get.isDarkMode ? 0 : 1);
},
child: Text('主题修改'),
)
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class ThemeController extends GetxController {
//0:正常模式 1:黑夜模式
var _darkMode = 0;
get darkMode => _darkMode;
// void changeMode(value) {
// _darkMode = value;
// Get.changeTheme(value == 0
// ? ThemeData.dark()
// : Get.isDarkMode
// ? ThemeData.light()
// : ThemeData.dark());
// update();
// }
void changeMode(value) {
_darkMode = value;
Get.changeTheme(value == 0 ? ThemeData.light() : ThemeData.dark());
update();
}
}
4.判断是否为黑夜模式
Theme.of(context).brightness == Brightness.dark;
5.如何适配颜色
提供一种思路:如同国际化类似,我们通过模式来区分,获取不同的color颜色组