공유 상태 관리(InheritedWidget)는 사용하기 쉽습니다.

공유 상태 관리 - InheritedWidget의 간단한 사용

InheritedWidget위젯 트리에서 위에서 아래로 데이터를 공유하는 방법을 제공하는 Flutter에서 매우 중요한 기능적 구성 요소이며,

InheritedWidget와 Reactin 의 기능 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호출하여 인스턴스를 가져 오고 공유 데이터 카운터를 가져옵니다.CounterWidgetCounterWidget

     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
    

효과는 다음과 같습니다.
여기에 이미지 설명 삽입

추천

출처blog.csdn.net/MrLizuo/article/details/127770093