개발노트

45. [Flutter] 앱 전체에 데이터 공유 및 수정하기, 상태 관리(with ChangeNotifier, ValueNotifier) 본문

앱 개발/Flutter

45. [Flutter] 앱 전체에 데이터 공유 및 수정하기, 상태 관리(with ChangeNotifier, ValueNotifier)

mroh1226 2023. 11. 9. 15:51
반응형

ChangeNotifier, ValueNotifier

상태관리를 해주는 Class가 있다면 다른 화면에서도 서로 값을 공유할 수 있습니다.

이를 구현하기 위해 2가지 Notifier를 소개하겠습니다.


들어가기 전 회고.

.NET MAUI의 MVVM패턴 개발에 사용되었던 Notify.cs 의 Notification 과 유사한 점이 많아 이해하기 수월했습니다.

MAUI에서 처럼 매개변수로 받은 인자 값를 Get, Set 하며 값의 변경이 있었을 때, INotifyPropertyChanged에 알려주고 Property의 값을 변경하는 방식이 떠올랐습니다.

 

- MAUI의 INotifyPropertyChanged 포스팅: https://mroh1226.tistory.com/6

 

4. [.NET MAUI] INotifyPropertyChanged 인터페이스 상속하기(MVVM 패턴)

MAUI는 MVU 모델을 지원한다고한다. 아직은 학습자료가 부족하기 때문에 자마린으로 경험해본 MVVM 패턴으로 개발하려고한다. 솔루션에 분류를 위해 디렉토리를 생성해준다. INotifyPropertyChanged 인터

mroh1226.tistory.com

 

아마 Flutter 앱 MVVM 패턴으로 가기위한 개념 설명이지 않을까 생각이 들었으며, MAUI 방식보다 훨씬 간편하고 직관적이였습니다.


ChangeNotifier

앞서 포스팅했던 InheritedWidget을 사용하는 방식과 ChangeNotifier를 비교했을 때 크게 유사한점과 다른점은 다음과 같았습니다.

  • 유사점: class 내에 작성된 변수를 앱 내 전체에서 다룰 수 있는 점(main.dart에 최상위로 줬을 때)
  • 다른점: 변수값을 수정하기 위해 StatefulWidget의 child로 들어가 Function() 을 상속받을 필요 없이 class 내에 바로 작성해서 사용하는 점

ChangeNotifier  사용 예시.

1. ChangeNotifier를 상속 받는 class를 만들어줍니다. 👉🏻 VideoConfig

2. 관리할 변수들과 메소드를 작성해줍니다. 👉🏻 autoMute, toggleAutoMute()

3. 완성된 class를 사용하기 위해 하나 생성해줍니다. 👉🏻 final videoConfig = VideoConfig();

import 'package:flutter/foundation.dart';

class VideoConfig extends ChangeNotifier {
  bool autoMute = true;

  void toggleAutoMute() {
    autoMute = !autoMute;
    notifyListeners();
    //바뀌었다고 알려주기
  }
}

final videoConfig = VideoConfig();

4. 위에서 생성한 videoConfig 를 다른 화면, 위젯에서 사용하는 2가지 방법이 있습니다.

 

4-1) AnimatedBuilder 를 사용하는 방법

AnimatedBuilder(
	title: const Text('Auto Mute'),
	animation: videoConfig,
	builder: (context, child) => SwitchListTile.adaptive(
		value: videoConfig.autoMute,
		onChanged: (value) {
			videoConfig.toggleAutoMute();
		},
	),
),
  • AnimatedBuilder로 videoConfig 데이터가 필요한 위젯을 감싸줍니다.
  • AnimatedBuilder의 animation: 속성에 videoConfig 를 넣어줍니다.
  • videoConfig.autoMute, videoConfig.toggleAutoMute() 를 원하는 곳에 사용합니다.

 

4-2) addLisener 를 사용하는 방법

bool _autoMute = videoConfig.autoMute;

@override
  void initState() {
    super.initState();

    videoConfig.addListener(() {
      setState(() {
        _autoMute = videoConfig.autoMute;
      });
    });
  }
  
  
  ...
  ...
  //위젯 파트
  IconButton(
	onPressed: videoConfig.toggleAutoMute,
	icon: Icon(
    	size: 32,
    	_autoMute ? Icons.volume_off : Icons.volume_up,
		)
	)
  • videoConfig.autoMute 값을 받을 bool형 변수 _autoMute 를 생성해줍니다.
  • void initStae(){} 에 videoConfig.addListener((){}) 를 넣어 이벤트 리스너를 생성하여 리스너가 상태관리를 하도록 만들어 줍니다.
  • setStae((){}) 에 _autoMute = videoConfig.autoMute; 를 넣어 변수 상태가 업데이트 되도록 만들어줍니다.
  • videoConfig.toggleAutoMute, _autoMute를 위젯파트에서 목적에 따라 사용합니다.

ValueNotifier

ValueNotifier하나의 변수만이 필요할때 간단하게 생성하여 사용할 수 있습니다.

(여러변수나, 메소드 등이 필요하다면 Class 형태인 ChangeNotifier를 상속받아 사용해야합니다.)

 

1. 아래와 같이 값이 들어갈 변수에 ValueNotifier(변수값) 형태로 생성하면 끝입니다.

(true,false 를 넣으면 bool형 / 1,2,3,4... 를 넣으면 int형 등.. 이 됩니다.)

import 'package:flutter/foundation.dart';

final videoConfig = ValueNotifier(false);
//하나의 변수만 지원함
  • ValueNotifier를 통해 초기 false 값을 갖는 bool 형 videoConfig를 생성합니다.

 

2. 포함한 값이 하나기 때문에 뒤에 value 만 붙여주면됩니다.

AnimatedBuilder(
	title: const Text('Auto Mute'),
	animation: videoConfig,
	builder: (context, child) => SwitchListTile.adaptive(
		value: videoConfig.value,
		onChanged: (value) {
			videoConfig.value = !videoConfig.value;
		},
	),
),
  • 사용하는 2가지 방식은 ChangeNotifier 과 동일하며,
  • videoConfig.value 로 값을 사용하면 됩니다.

ChangeNotifier, ValueNotifier를 이용하여 서로 다른 화면에서 같은 값을 사용하는 모습.

 

반응형
Comments