공유 상태 관리 - InheritedWidget의 간단한 사용
InheritedWidget
위젯 트리에서 위에서 아래로 데이터를 공유하는 방법을 제공하는 Flutter에서 매우 중요한 기능적 구성 요소이며,
InheritedWidge
t와 React
in 의 기능 context
은 유사하며 구성 요소 간 데이터 전송을 실현할 수 있습니다. InheritedWidget
위젯 트리에서 데이터 전송 방향은 위에서 아래로입니다.
InheritedWidget
먼저 소스코드를 보고 ,
- InheritedWidget의 구성에서 자식을 전달해야 하며 이 자식은 공유 데이터를 사용해야 하는 하위 위젯입니다.
- updateShouldNotify 이 추상 메서드는 하위 클래스에서 구현해야 합니다.
abstract class InheritedWidget extends ProxyWidget {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const InheritedWidget({
super.key, required super.child });
InheritedElement createElement() => InheritedElement(this);
/// Whether the framework should notify widgets that inherit from this widget.
///
/// When this widget is rebuilt, sometimes we need to rebuild the widgets that
/// inherit from this widget but sometimes we do not. For example, if the data
/// held by this widget is the same as the data held by `oldWidget`, then we
/// do not need to rebuild the widgets that inherited the data held by
/// `oldWidget`.
///
/// The framework distinguishes these cases by calling this function with the
/// widget that previously occupied this location in the tree as an argument.
/// The given widget is guaranteed to have the same [runtimeType] as this
/// object.
bool updateShouldNotify(covariant InheritedWidget oldWidget);
}
"카운터" 샘플 애플리케이션에 대한 공유 데이터를 정의하려면 다음과 같이 InheritedWidget
에서 상속해야 합니다 . InheritedWidget
class CounterWidget extends InheritedWidget {
// 1.需要共享的数据
final int counter;
// 2.定义构造方法 传入最新的 counter值
CounterWidget({
this.counter, Widget child}): super(child: child);
// 3.获取组件最近的当前InheritedWidget
static CounterWidget of(BuildContext context) {
// 沿着Element树, 去找到最近的CounterElement, 从Element中取出Widget对象
return context.dependOnInheritedWidgetOfExactType();
}
// 4.绝对要不要回调State中的didChangeDependencies
// 如果返回true: 执行依赖当期的InheritedWidget的State中的 didChangeDependencies
bool updateShouldNotify(CounterWidget oldWidget) {
return oldWidget.counter != counter;
}
}
-
공유할 데이터는 int 유형의 카운터입니다.
-
구성에서 카운터에 값을 할당하고 자식은 데이터를 사용해야 하는 위젯입니다.
-
컨텍스트를 통해 조상을 찾기 시작하는 of 메서드를 정의합니다.
CounterWidget
-
updateShouldNotify
방법은 old 와 new 를 비교CounterWidget
하고 이에 의존하는 Widget을 업데이트할지 여부입니다.true를 반환하는 경우: 실행은 현재 InheritedWidget의 상태에 따라 다릅니다.
didChangeDependencies
예제에서 사용하려면 CounterWidget
공유 데이터를 사용하도록 ShowDataWidget 하위 구성 요소를 정의합니다.
class _HomePageState extends State<HomePage> {
int _counter = 100;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("InheritedWidget"),
),
body: CounterWidget(//使用CounterWidget 将需要使用数据widget包裹
counter: _counter,
child: Center(
child: ShowDataWidget(),//在ShowDataWidget 中去使用共享的数据
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
setState(() {
_counter++;
});
},
),
);
}
}
class ShowDataWidget extends StatefulWidget {
_ShowDataWidgetState createState() => _ShowDataWidgetState();
}
class _ShowDataWidgetState extends State<ShowDataWidget> {
void didChangeDependencies() {
super.didChangeDependencies();
print("执行了ShowDataWidget中的didChangeDependencies");
}
Widget build(BuildContext context) {
int counter = CounterWidget.of(context).counter;
return Card(
color: Colors.red,
child: Text("当前计数: $counter", style: TextStyle(fontSize: 30),),CounterWidget
);
}
}
우리는 다음을 볼 수 있습니다.
-
여기에서 floatingActionButton을 누른 후 setState를 호출하여 _HomePageState의 빌드 메서드를 다시 호출한 다음 다시 생성하여
CounterWidget
최신 카운터 값을 전달합니다. -
에서 **of** 메서드를
ShowDataWidget
호출하여 인스턴스를 가져 오고 공유 데이터 카운터를 가져옵니다.CounterWidget
CounterWidget
int counter = CounterWidget.of(context).counter;
-
_ShowDataWidgetState
메소드 가didChangeDependencies
호출되는 것을 볼 수 있습니다.didChangeDependencies
이 메서드는 "종속성"이 변경될 때 Flutter 프레임워크에 의해 호출 됩니다. 그리고 이 "종속성"은 하위 위젯이 상위 위젯의 InheritedWidget 데이터를 사용하는지 여부를 나타냅니다! 사용하면 하위 위젯에 종속성이 있음을 의미하고, 사용하지 않으면 종속성이 없음을 의미합니다. 이 메커니즘을 통해 종속 InheritedWidget이 변경될 때 하위 구성 요소가 스스로 업데이트할 수 있습니다! 예를 들어 테마, 로케일(언어) 등이 변경되면 이에 의존하는 하위 위젯의 didChangeDependencies 메소드가 호출됩니다.2022-11-09 13:11:06.175 14203-14233/com.example.learn_flutter I/flutter: 执行了_ShowData01State中的didChangeDependencies 2022-11-09 13:11:07.383 14203-14233/com.example.learn_flutter I/flutter: 执行了_ShowData01State中的didChangeDependencies 2022-11-09 13:11:08.248 14203-14233/com.example.learn_flutter I/flutter: 执行了_ShowData01State中的didChangeDependencies 2022-11-09 13:11:08.999 14203-14233/com.example.learn_flutter I/flutter: 执行了_ShowData01State中的didChangeDependencies
효과는 다음과 같습니다.