Переключатель тёмного режима
Часть раздела Адаптивная компоновка путешествия по Flutter на Coddy. Урок 25 из 30.
Некоторым пользователям нужен тёмный режим в одном приложении, но не в остальных. Дайте им переключатель.
themeMode: — это такая же настройка, как и любая другая, поэтому её значение может поступать из состояния. Храните bool в состоянии State виджета MyApp, который создаёт MaterialApp, и выбирайте режим на его основе:
bool _dark = false;
MaterialApp(
themeMode: _dark ? ThemeMode.dark : ThemeMode.light,
...
)Когда переключатель меняет значение _dark внутри setState, функция build запускается снова, MaterialApp получает новый режим, и тема на всех экранах меняется одновременно с коротким затуханием.
Состояние должно находиться выше MaterialApp, потому что именно там выбирается тема. Поэтому здесь MyApp — это StatefulWidget.
Задание
ЛегкоСделай так, чтобы переключатель менял тему:
- в
onChangedсохрани новое значение в_darkвнутриsetState - задай
themeMode:уMaterialAppна основе_dark: тёмная, если значение true, светлая, если false
Попробуйте сами
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _dark = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.indigo,
brightness: Brightness.dark,
),
),
home: Scaffold(
appBar: AppBar(title: const Text('Night Reader')),
body: Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Dark mode', style: TextStyle(fontSize: 20)),
const SizedBox(width: 12),
Switch(
value: _dark,
onChanged: (value) {},
),
],
),
),
),
);
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Адаптивная компоновка
1Совместное размещение в строке
Expanded заполняет строкуДелим пространство с flexFlexible подстраивается под размер дочернего элементаSpacer раздвигает элементы2Ошибка переполнения
Ошибка переполненияИсправление переполнения: расширениеИсправление переполнения: прокруткаИсправление переполнения: переносИнтервалы внутри переноса5Перечисления и switch
Перечисления для типов экрановКонструкция switch с перечислениемВыражения switch3Компоновка виджетов в стопку
Расположить виджеты друг над другомРазмещение в углуВыравнивание внутри блокаSafeArea и вырез экрана6Темы и тёмный режим
Тема приложения на основе seedЦвета Theme.of(context)Стили текста из темыТёмная темаПереключатель тёмного режимаПотренируйтесь самостоятельно: Онлайн-компилятор Flutter