InheritedWidget
使用InheritedWidget的几个步骤如下:1. 创建一个继承自InheritedWidget的自定义类,用于共享数据。这个类应该包含一个数据字段和一个updateShouldNotify方法,用于确定是否需要更新依赖于该数据的Widget。例如:
class MyInheritedWidget extends InheritedWidget {
final String data;
MyInheritedWidget({required this.data, required Widget child})
: super(child: child);
@override
bool updateShouldNotify(MyInheritedWidget oldWidget) {
return oldWidget.data != data;
}
}
2. 在需要共享数据的Widget树中,将自定义的InheritedWidget作为父级Widget包裹住子Widget。例如:
MyInheritedWidget(
data: 'Hello, InheritedWidget!',
child: MyChildWidget(),
)
3. 在子Widget中,通过 `MyInheritedWidget.of(context)` 来获取共享的数据。例如:
final inheritedData = MyInheritedWidget.of(context).data;
4. 当数据发生变化时,通过更改InheritedWidget的数据字段来触发更新。这将自动更新依赖于该数据的Widget。
这些是使用InheritedWidget的基本步骤。通过这种方式,您可以在整个Widget树中共享数据,并且当数据变化时,依赖于该数据的Widget会自动更新。请注意,当数据发生变化时,只有依赖于该数据的Widget才会进行重建,而其他Widget不会受到影响,这有助于提高性能。
import 'package:flutter/material.dart'; // 导入Flutter Material库
// 创建一个InheritedWidget
class MyInheritedWidget extends InheritedWidget {
final String data; // 要共享的数据
// 构造函数,需要传入共享数据和子Widget
MyInheritedWidget({required this.data, required Widget child})
: super(child: child); // 调用父类构造函数
// 重写updateShouldNotify方法,用于判断是否需要通知更新.
/*
当InheritedWidget中的updateShouldNotify方法返回false时,子widget只会调用didUpdateWidget和build方法。
而当updateShouldNotify方法返回true时,子widget会依次调用didUpdateWidget、didChangeDependencies和build方法。
这意味着当updateShouldNotify返回true时,子widget会收到更多的更新通知,并且在更新过程中会执行更多的方法。
因此,在使用InheritedWidget时,需要根据具体业务需求来确定是否需要让子widget接收更多的更新通知。
* */
@override
bool updateShouldNotify(MyInheritedWidget oldWidget) {
return oldWidget.data != data; // 如果data发生变化,则返回true,表示需要通知更新
}
// 静态方法,用于从BuildContext获取最近的MyInheritedWidget实例
static MyInheritedWidget of(BuildContext context) {
final inheritedWidget = context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>(); // 从BuildContext中获取最近的MyInheritedWidget实例
if (inheritedWidget == null) { // 如果获取不到MyInheritedWidget实例,则抛出异常
throw Exception('MyInheritedWidget not found in the widget tree.');
}
return inheritedWidget; // 返回获取到的MyInheritedWidget实例
}
}
// 使用InheritedWidget的Widget
class MyChildWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 从InheritedWidget中获取数据
final inheritedData = MyInheritedWidget.of(context).data; // 从InheritedWidget中获取共享数据
return Container( // 创建一个容器Widget
child: Text(inheritedData), // 在容器中显示获取到的共享数据
);
}
}
// 根Widget
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp( // 创建一个MaterialApp Widget作为根Widget
home: MyInheritedWidget( // 在MaterialApp的home属性中使用自定义的InheritedWidget,让使用的下级widget查找
data: 'Hello, InheritedWidget!你是我设置的数据', // 设置共享数据为'Hello, InheritedWidget!'
child: Scaffold( // 创建一个Scaffold Widget作为子Widget
appBar: AppBar( // 在Scaffold的appBar属性中创建一个AppBar Widget
title: Text('InheritedWidget示例'), // 设置AppBar的标题为'InheritedWidget示例'
),
body: Center( // 在Scaffold的body属性中创建一个Center Widget作为子Widget
child: MyChildWidget(), // 在Center中使用自定义的MyChildWidget Widget,它将从InheritedWidget中获取共享数据并显示
),
),
),
);
}
}
void main() {
runApp(MyApp()); // 启动应用程序
}
provider
1、新一个共享的数据文件ViweModa.dart
import 'package:flutter/material.dart';
class HYViweModa extends ChangeNotifier{
int _counter=100;
int get counter => _counter;
set counter(int value) {
_counter = value;
notifyListeners();//调用notifyListeners()方法来通知监听器。
}
}
2、使用
import 'package:flutter/material.dart';
import 'package:my1/ViweModa.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
// ChangeNotifierProvider(
// create:(ctx){
// return HYViweModa();
// } ,
// child: YourApp(),
// )
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => HYViweModa()),
],
child: YourApp(),
),
);
}
class YourApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "flutter dome",
home: HYpage(),
);
}
}
class HYpage extends StatelessWidget {
const HYpage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("测试"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
HY01(),
HY02(),
HY03(),
Selector<HYViweModa,HYViweModa>(//第三种方法,优化后完全不用重构
selector: (context, provider) => provider,//不转换为S
shouldRebuild: (previous, Tnext){
return false;//返回false不重新构建
},
builder:(context, data, child) {
// 使用共享的数据构建你的Widget
return ElevatedButton(
onPressed: () {
// 按下按钮后的操作
data.counter-=1;
},
child: Icon(Icons.remove),
);
},
),
],
),
),
floatingActionButton: Consumer<HYViweModa>(//第二种方法的优化
builder: (ctx,counterVM,ch){
return FloatingActionButton(
child: ch,//下面传入的
onPressed: () {
counterVM.counter+=1;
},
);
},
child: Icon(Icons.add),//优化,不用重新构建,传入到ch中
),
);
}
}
class HY01 extends StatelessWidget {
@override
Widget build(BuildContext context) {
//第一种方法
int counter=Provider.of<HYViweModa>(context).counter;
return Container(
color: Colors.blue,
child: Text("当前计数:$counter",style: TextStyle(fontSize: 30),),
);
}
}
class HY02 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Consumer<HYViweModa>(//第二种方法
builder: (ctx,counterVM,child){
return Text("当前计数:${counterVM.counter}",style: TextStyle(fontSize: 30),);
},
)
);
}
}
class HY03 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.orangeAccent,
child: Consumer2<HYViweModa,HYViweModa>(//第四种方法,可多个
builder: (ctx,counterVM,counterVM2,child){
return Text("当前计数:${counterVM2.counter}",style: TextStyle(fontSize: 30),);
},
)
);
}
}