Provider 사용 방법 이해

19685 단어 Flutterprovidertech
Provider 포장은 InheritedWidget의 포장 창고입니다.하위 트리의 Widget에서 상위 트리의 Widget에 액세스하여 상태를 관리하는 방법을 제공합니다.Google I/O'19에도 소개되어 있으며 매우 일반적인 패키지입니다.
https://youtu.be/d_m5csmrf7I

이루어지다


샘플 소스는 아래에 놓으세요.
https://github.com/NAOYA-MAEDA-DEV/flutter_provider_sample
Increant Count A/B/C 버튼을 클릭하면 Counter A, Counter C 디스플레이가 업데이트됩니다.작업을 확인하기 위해 "Counter B"디스플레이가 업데이트되지 않습니다.

샘플 출처 설명


Provider 설치


pubspec.yaml 편집 후 설치Provider.dependenciesprovider: ^6.0.2를 추가하고 Pub Get를 실행하십시오.
pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.2

ChangeNotifier가 상속된 상태 수준 설정


counter.dart
class Counter extends ChangeNotifier {
  var countA = 0;
  var countB = 0;
  var countC = 0;

  void incrementCounterA() {
    countA++;
    notifyListeners();
  }

  void incrementCounterB() {
    countB++;
    notifyListeners();
  }

  void incrementCounterC() {
    countC++;
    notifyListeners();
  }
}

  • ChangeNotifierChangeNotifier는 청중에게 변경 통지를 하는 기능을 제공하는 학급이다.카운터 클래스는 ChangeNotifier를 계승한 후 사용할 수 있다notifyListeners.

  • notifyListeners
    청중에게 변경 통지를 보내다.
  • counta/B/C는 하위 트리 위젯에서 액세스하는 상태 변수입니다.credentCounterA/B/C 방법은counta/B/C를 각각 증가시키는 방법입니다.

    상태 클래스를 상위 트리에 배치


    main.dart
    ChangeNotifierProvider(
      create: (context) => Counter(),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: const [
          TextWidgetA(),
          TextWidgetB(),
          TextWidgetC(),
          ButtonWidgetA(),
          ButtonWidgetB(),
          ButtonWidgetC()
        ],
      ),
    ),
    

  • ChangeNotifierProvider
    상위 트리에 배치ChangeNotifierProvider.create 상속ChangeNotifier 대상을 되돌려 주는 함수를 지정합니다.하위 트리의 Widget을 child에 구성합니다.
  • 하위 트리의 Widget에서 상위 트리의 상태 클래스에 액세스


    사용 context.watch, context.read, context.select 중 상위 트리에 액세스하는 상태 범주입니다.
  • context.watch
  • main.dart
    class WidgetA extends StatelessWidget {
      const WidgetA({Key? key}) : super(key: key);
    
      
      Widget build(BuildContext context) {
        print('Built WidgetA');
    
        return Center(
            child: Text(
                'Counter A: ${context.watch<Counter>().countA}',
                style: const TextStyle(
                    fontSize: 20
                )
            )
        );
      }
    }
    
    context.watch 상태류의 변화를 감시한다.상태 카테고리notifyListeners를 실행하면 사용context.watch의 부품 변경 사항을 알리고 부품을 재구성합니다.
  • context.read
  • main.dart
    class TextWidgetB extends StatelessWidget {
      const TextWidgetB({Key? key}) : super(key: key);
    
      
      Widget build(BuildContext context) {
        print('Built TextWidgetB');
    
        return Center(
            child: Text(
                'Counter B: ${context.read<Counter>().countB}',
                style: const TextStyle(
                    fontSize: 20
                )
            )
        );
      }
    }
    
    context.read 상태류의 변화를 감시하지 않는다.실행 상태 범주notifyListeners에도 사용context.read된 부품이 변경되었음을 알리지 않으며 부품이 재구성되지 않습니다.
    main.dart
    context.read<Counter>().incrementCounterA()
    
    Buton WidgetA/B/C 내context.read에서increament CounterA/B/C를 통해 호출됩니다.상태 클래스를 호출할 때 사용합니다context.read.
  • context.select
  • main.dart
    class TextWidgetC extends StatelessWidget {
      const TextWidgetC({Key? key}) : super(key: key);
    
      
      Widget build(BuildContext context) {
        print('Built TextWidgetC');
    
        return Center(
            child: Text(
                'Counter C: ${context.select((Counter counter) => counter.countC)}',
                style: const TextStyle(
                    fontSize: 20
                )
            )
        );
      }
    }
    
    context.select 상태 클래스에서 특정 대상의 변화를 감시한다.상태 클래스 notifyListeners 를 실행할 때 context.select 에서 지정한countc의 상태가 변할 때만 위젯의 변경 사항을 알려주고 위젯을 재구성합니다.

    실행 결과


    Increant Count A 버튼을 클릭합니다.Counter 객체의 increamenta를 실행하여 counta를 증가시킵니다.TextWidgetA에서는 context.watch를 사용하여 Counter 대상에 접근하기 때문에 Counter 대상이 변경되면 TextWidgetA가 재구성되고'인크레임 Counta'단추를 누르는 횟수가 업데이트됩니다.

    그런 다음 Increament Count B 버튼을 클릭합니다.Counter 객체의 increamentB를 실행하여 countB를 증가시킵니다.TextWidgetB에서 context.read를 사용하여 Counter 대상에 접근하기 때문에 Counter 대상이 변경되었더라도 TextWidgetB는 재구성되지 않으며'인크레임 CountB'단추를 눌렀을 때의 디스플레이는 업데이트되지 않습니다.

    마지막으로 Increament Count C 버튼을 클릭합니다.Counter 객체의 increamentc를 실행하여 countc를 증가시킵니다.TextWidgetC는 context.select를 사용하여 Counter 객체에 액세스합니다.또한,countc의 변경 사항을 감시하기 때문에countc가 변경될 때TextWidgetC는 재구성되어 "Incretment Countc"단추를 눌렀던 횟수의 디스플레이를 업데이트합니다.

    더 깊이 들어가서 TextWidgetA/TextWidgetB/TextWidgetC가 재건될 시기를 확인하십시오.Increant Count A 버튼을 클릭합니다.TextWidgetA가 재구성되어 콘솔에 "fluter: Built TextWidgetA"가 표시됩니다.

    그런 다음 Increament Count B 버튼을 클릭합니다.TextWidgetB를 다시 만들지 않았습니다. 콘솔에 'fluter: Built TextWidgetA' 만 표시됩니다.

    TextWidgetB에서는 context.read를 사용하여 Counter 대상에 접근했기 때문에 Counter 대상이 변경되었더라도 TextWidgetB는 변경을 알리지 않고 TextWidgetB는 재구성되지 않습니다.그러나 TextWidgetA는 context.watch를 사용하여 Counter 대상에 접근했기 때문에counterB가 점차적으로 증가하여 Counter 대상의 변경을 감지했다.결과적으로 "Increament Count B"단추를 눌렀을 때 TextWidgetA의 변경 사항만 알렸고, TextWidgetA가 재구성되었습니다.
    마지막으로 Increament Count C 버튼을 클릭합니다.Counter 객체는countc가 증가함에 따라 변경되며 TextWidgetA는 재구성됩니다.또한countc가 점차적으로 증가하여countc를 감시하는 TextWidgetC가 재구성됩니다.그 결과 콘솔에 "fluter: Built TextWidget A", "fluter: Built TextWidget C"가 표시됩니다.

    좋은 웹페이지 즐겨찾기