flutter_provider_demo

This commit is contained in:
2025-02-17 21:26:52 +08:00
commit 68259775e7
135 changed files with 5653 additions and 0 deletions

View File

@ -0,0 +1,360 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// 修改UserInfo为可变的
class UserInfo extends ChangeNotifier {
String _name;
int _age;
String _email;
UserInfo({
required String name,
required int age,
required String email,
}) : _name = name,
_age = age,
_email = email;
String get name => _name;
int get age => _age;
String get email => _email;
void updateName(String newName) {
_name = newName;
notifyListeners();
}
void incrementAge() {
_age++;
notifyListeners();
}
void updateEmail(String newEmail) {
_email = newEmail;
notifyListeners();
}
}
// 修改AppConfig为可变的
class AppConfig extends ChangeNotifier {
String _theme;
String _language;
AppConfig({
required String theme,
required String language,
}) : _theme = theme,
_language = language;
String get theme => _theme;
String get language => _language;
void toggleTheme() {
_theme = _theme == 'light' ? 'dark' : 'light';
notifyListeners();
}
void toggleLanguage() {
_language = _language == 'en' ? 'zh' : 'en';
notifyListeners();
}
}
class BasicProviderPage extends StatelessWidget {
const BasicProviderPage({super.key});
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
// 提供单个值
Provider<String>.value(value: 'Hello from Basic Provider!'),
// 提供可变的用户信息
ChangeNotifierProvider(
create: (_) => UserInfo(
name: 'John Doe',
age: 30,
email: 'john@example.com',
),
),
// 提供可变的配置信息
ChangeNotifierProvider(
create: (_) => AppConfig(
theme: 'light',
language: 'en',
),
),
],
child: Scaffold(
appBar: AppBar(
title: const Text('Basic Provider')
),
body: const SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
WatchExample(),
SizedBox(height: 20),
ReadExample(),
SizedBox(height: 20),
SelectExample(),
SizedBox(height: 20),
ConsumerExample(),
SizedBox(height: 20),
OfExample(),
SizedBox(height: 20),
UpdateSection(),
],
),
),
),
),
);
}
}
// 添加新的更新部分
class UpdateSection extends StatelessWidget {
const UpdateSection({super.key});
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Update Examples:',
style: TextStyle(fontWeight: FontWeight.bold)),
const SizedBox(height: 10),
// 用户信息更新按钮
const Text('User Info Updates:'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () {
context.read<UserInfo>().updateName(
context.read<UserInfo>().name == 'John Doe'
? 'Jane Doe'
: 'John Doe');
},
child: const Text('Toggle Name'),
),
ElevatedButton(
onPressed: () => context.read<UserInfo>().incrementAge(),
child: const Text('Increment Age'),
),
ElevatedButton(
onPressed: () {
final currentEmail = context.read<UserInfo>().email;
context.read<UserInfo>().updateEmail(
currentEmail == 'john@example.com'
? 'jane@example.com'
: 'john@example.com');
},
child: const Text('Toggle Email'),
),
],
),
const SizedBox(height: 10),
// 配置更新按钮
const Text('App Config Updates:'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () => context.read<AppConfig>().toggleTheme(),
child: const Text('Toggle Theme'),
),
ElevatedButton(
onPressed: () => context.read<AppConfig>().toggleLanguage(),
child: const Text('Toggle Language'),
),
],
),
// 实时显示当前值
const SizedBox(height: 10),
const Text('Current Values:'),
Consumer<UserInfo>(
builder: (context, userInfo, _) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Name: ${userInfo.name}'),
Text('Age: ${userInfo.age}'),
Text('Email: ${userInfo.email}'),
],
),
),
const SizedBox(height: 5),
Consumer<AppConfig>(
builder: (context, config, _) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Theme: ${config.theme}'),
Text('Language: ${config.language}'),
],
),
),
],
),
),
);
}
}
// 使用 watch 方式访问数据(会监听变化)
class WatchExample extends StatelessWidget {
const WatchExample({super.key});
@override
Widget build(BuildContext context) {
final String message = context.watch<String>();
final userInfo = context.watch<UserInfo>();
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Watch Example:',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('Message: $message'),
Text('User: ${userInfo.name}, Age: ${userInfo.age}'),
],
),
),
);
}
}
// 使用 read 方式访问数据(不会监听变化)
class ReadExample extends StatelessWidget {
const ReadExample({super.key});
@override
Widget build(BuildContext context) {
// read 适合在事件处理中使用
final userInfo = context.read<UserInfo>();
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Read Example: ${userInfo.name}',
style: TextStyle(fontWeight: FontWeight.bold)),
ElevatedButton(
onPressed: () {
final userInfo = context.read<UserInfo>();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Email: ${userInfo.email}')),
);
},
child: const Text('Show User Email'),
),
],
),
),
);
}
}
// 使用 select 方式访问数据(只监听特定字段)
class SelectExample extends StatelessWidget {
const SelectExample({super.key});
@override
Widget build(BuildContext context) {
final language = context.select((AppConfig config) => config.language);
final theme = context.select((AppConfig config) => config.theme);
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Select Example:',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('Language: $language'),
Text('Theme: $theme'),
],
),
),
);
}
}
// 使用 Consumer 方式访问数据
class ConsumerExample extends StatelessWidget {
const ConsumerExample({super.key});
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Consumer Example:',
style: TextStyle(fontWeight: FontWeight.bold)),
Consumer<UserInfo?>(
builder: (context, userInfo, child) {
if (userInfo == null) {
return const Text('UserInfo not provided');
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Name: ${userInfo.name}'),
Text('Age: ${userInfo.age}'),
Text('Email: ${userInfo.email}'),
],
);
},
),
],
),
),
);
}
}
// 使用 Provider.of 方式访问数据
class OfExample extends StatelessWidget {
const OfExample({super.key});
@override
Widget build(BuildContext context) {
// listen: false 类似于 read
final appConfig = Provider.of<AppConfig>(context, listen: false);
// listen: true 类似于 watch
final userInfo = Provider.of<UserInfo>(context, listen: true);
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Provider.of Example:',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('Theme: ${appConfig.theme}'),
Text('User: ${userInfo.name}'),
],
),
),
);
}
}