面试题答案
一键面试设计状态管理逻辑思路
- 创建共享状态类:使用
ChangeNotifier
来创建一个包含主题模式等共享状态的类。例如,主题模式可以用枚举来表示。 - Provider 包裹:在应用顶层使用
Provider
包裹整个应用,以便各个组件都能获取到共享状态。 - 选择合适的 Consumer:根据组件需求,使用
Consumer
或Selector
来订阅状态变化。Selector
适用于只关注部分状态变化的组件,可避免不必要的重建。
示例代码结构
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// 定义主题模式枚举
enum ThemeModeEnum { light, dark }
// 共享状态类
class ThemeModel extends ChangeNotifier {
ThemeModeEnum _themeMode = ThemeModeEnum.light;
ThemeModeEnum get themeMode => _themeMode;
void toggleTheme() {
_themeMode = _themeMode == ThemeModeEnum.light
? ThemeModeEnum.dark
: ThemeModeEnum.light;
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => ThemeModel(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final themeModel = Provider.of<ThemeModel>(context);
final isDark = themeModel.themeMode == ThemeModeEnum.dark;
return MaterialApp(
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
themeMode: isDark? ThemeMode.dark : ThemeMode.light,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('混合开发示例'),
),
body: Column(
children: [
// 使用Selector避免不必要重建,只关注themeMode
Selector<ThemeModel, ThemeModeEnum>(
selector: (context, themeModel) => themeModel.themeMode,
builder: (context, themeMode, child) {
return Text(
'当前主题: ${themeMode == ThemeModeEnum.light? 'Light' : 'Dark'}',
);
},
),
CupertinoButton(
child: Text('切换主题'),
onPressed: () {
Provider.of<ThemeModel>(context, listen: false).toggleTheme();
},
),
],
),
);
}
}
在这个示例中,ThemeModel
类管理主题模式状态。MyApp
根据主题模式设置 MaterialApp
的主题。HomePage
中的 Selector
只关注主题模式变化,CupertinoButton
用于切换主题状态。这样可以确保状态变化能正确传递,同时避免不必要的重建。