[Flutter] ValueNotifier, ChangeNotifier

2024. 1. 29. 09:58dev/flutter

728x90
반응형

플루터에서 UI를 변경하기 위해서 StatefulWidget을 사용하고, setState메서드를 사용하여 UI를 변경한다.

이것이 기초중의 기초.

 

하지만, 계속해서 setState를 사용하여 build를 하게 되면 UI 전체가 갱신되기 때문에 부분적인 값만 변경하는 경우 불필요하다. 그래서 찾게 된 것이 ValueNotifier.

 

특정 값만을 변경하기 위해서는 ValueNotifier을 사용한다.

원하는 타입을 제네릭으로 넣어 상속하여 준다.

class NotifyFriend extends ValueNotifier<int> {
  NotifyFriend({int value = 0}):super(value);

  void increment() {
    value++;
  }

  void normalMethod() {

  }

  void notifyMethod() {
    notifyListeners();
  }
}

 

다른 초기화 방법

class _LuminanceState extends ValueNotifier<Color> {
  _LuminanceState({Color color = Colors.blueGrey}):
    super(color);
}

 

 

ValueNotifier클래스는 'value'값이 핵심이다.

increment함수를 보면 value값을 증가시키게 되는데,

증가가 되면서 현재 value값이 바뀌었다고 자동으로 알려주게 된다.

 

아무것도 선언하지 않은 normalMethod를 사용하면 아무 이벤트도 발생되지 않으며,

notifyMethod함수내 'notifyListener'함수를 사용하면 value값이 바뀌지 않아도 응답을 하게 된다.

 

응답을 받기위해서는 ValueListenableBuilder위젯을 만들어준다.

ValueListenableBuilder(
  valueListenable: notifyFriend,
  builder: (context, value, child) {
    debugPrint('ValueListenableBuilder..!!!! value:$value, child:$child');
    return Text('value:$value');
  },
),

 

 

값이 변경되면 기존 build함수가 재호출되는 것이 아닌 ValueListenableBuilder의 builder만 호출되게 된다.

 

 


ChangeNotifier도 마찬가지이다.

다시 UI가 전체 build되지 않고, 이벤트를 감지하는 부분만 변경된다.

Android의 DataBinding와 동일하다.

 

extends를 사용해도되고, with를 사용해도 된다.

사용할 클래스가 abstract로 설계된 클래스를 상속받고 있다면 with를 사용하고, 아니면 extends로 사용하는 것이 깔끔하다.

class ChangeNotifyFriend extends ChangeNotifier {
  int someone = 0;
  void change() {
    someone++;
    notifyListeners();
  }
}

 

 

감지는 ListenableBuilder에서 감지한다.

 

ListenableBuilder(
  listenable: changeNotifyFriend,
  builder: (context, child) {
    debugPrint('ListenableBuilder...!!!!! child:$child');
    return Text('changeNotifierListener...:${changeNotifyFriend.someone}');
  },
),

 

 

ValueNotifier나 ChangeNotifier나 둘 다 최초에 build된 이후로 사용하게 되는 시점에서 다시 re-build가 되는 점만 기억하고 UI의 흐름에 맞게 개발하면 될 것이다.

728x90
반응형

'dev > flutter' 카테고리의 다른 글

[Dart] getter, setter  (0) 2024.01.30
[Flutter] Don't use 'BuildContext's across async gaps  (0) 2024.01.29
[Flutter] SliverList  (0) 2024.01.27
[Flutter] Calendar, DateTime, Intl, TimeOfDay  (0) 2024.01.20
[Flutter] http, https  (0) 2024.01.20