인프런 커뮤니티 질문&답변

Link님의 프로필 이미지
Link

작성한 질문수

Flutter 앱 개발 실전

riverpod 코드 변환 질문

해결된 질문

작성

·

242

1

안녕하세요.

기회가 되신다면 코드 전체를 riverpod 버전으로 변경해서 notion 에 올려주실 수 있으실까요?

riverpod 버전으로 변경해보면서 Dart 문법에 대해 더 이해하게 되는 거 같습니다.

 

코드변환 질문1

class LangService with ChangeNotifier {
  /// 현재 언어
  Locale locale;

  LangService({
    Locale? locale,
  }) : locale = locale ?? IntlHelper.en;

  /// 언어 변경
  void toggleLang() {
    locale = IntlHelper.isKo ? IntlHelper.en : IntlHelper.ko;
    notifyListeners();
  }
}

위 코드를

final langProvider = NotifierProvider<LangNotifier, Locale?> (LangNotifier.new);

class LangNotifier extends Notifier<Locale?> {
  @override
  Locale? build() => IntlHelper.en;

  /// 언어 변경
  void toggleLang() {
    state = IntlHelper.isKo ? IntlHelper.en : IntlHelper.ko;
  }

}

로 변경하면 맞나요?

Notifier<Locale> 로 해야 하는지?

Notifier<Locale?> 로 해야 하는지요?

 

코드변환 질문2

class ThemeService with ChangeNotifier {
  ThemeService({
    AppTheme? theme,
  }) : theme = theme ?? LightTheme();

  /// 현재 테마
  AppTheme theme;

  /// 테마 변경
  void toggleTheme() {
    if (theme.brightness == Brightness.light) {
      theme = DarkTheme();
    } else {
      theme = LightTheme();
    }
    notifyListeners();
  }

  /// Material ThemeData 커스텀
  ThemeData get themeData {
    return ThemeData(
      /// Scaffold
      scaffoldBackgroundColor: theme.color.surface,

      /// AppBar
      appBarTheme: AppBarTheme(
        backgroundColor: theme.color.surface,
        elevation: 0,
        centerTitle: false,
        iconTheme: IconThemeData(
          color: theme.color.text,
        ),
        titleTextStyle: theme.typo.headline2.copyWith(
          color: theme.color.text,
        ),
      ),

      /// BottomSheet
      bottomSheetTheme: const BottomSheetThemeData(
        backgroundColor: Colors.transparent,
        constraints: BoxConstraints(
          maxWidth: Breakpoints.bottomSheet,
        ),
      ),
    );
  }
}

extension ThemeServiceExt on BuildContext {
  ThemeService get themeService => watch<ThemeService>();
  AppTheme get theme => themeService.theme;
  AppColor get color => theme.color;
  AppDeco get deco => theme.deco;
  AppTypo get typo => theme.typo;
}

위 코드를

final themeProvider = NotifierProvider<ThemeNotifier, AppTheme>(ThemeNotifier.new);

class ThemeNotifier extends Notifier<AppTheme> {
  @override
  AppTheme build() => LightTheme();

  AppTheme get theme => state;
  AppColor get color => state.color;
  AppDeco get deco => state.deco;
  AppTypo get typo => state.typo;

  /// 테마 변경
  void toggleTheme() {
    if (state.brightness == Brightness.light) {
      state = DarkTheme();
    } else {
      state = LightTheme();
    }
  }

  /// Material ThemeData 커스텀
  ThemeData get themeData {
    return ThemeData(
      /// Scaffold
      scaffoldBackgroundColor: state.color.surface,

      /// AppBar
      appBarTheme: AppBarTheme(
        backgroundColor: state.color.surface,
        elevation: 0,
        centerTitle: false,
        iconTheme: IconThemeData(
          color: state.color.text,
        ),
        titleTextStyle: state.typo.headline2.copyWith(
          color: state.color.text,
        ),
      ),

      /// BottomSheet
      bottomSheetTheme: const BottomSheetThemeData(
        backgroundColor: Colors.transparent,
        constraints: BoxConstraints(
          maxWidth: Breakpoints.bottomSheet,
        ),
      ),
    );
  }

}

로 변경하면 맞는지요?

답변 1

1

DevStory님의 프로필 이미지
DevStory
지식공유자

안녕하세요.

 

Q1. 기회가 되신다면 코드 전체를 riverpod 버전으로 변경해서 notion 에 올려주실 수 있으실까요?

Flutter 앱 개발 실전 MVVM & Test 파트 강의 자료 마지막에 Riverpod 버전 링크를 추가하였습니다.

 

Q2. Notifier<Locale> vs Notifier<Locale?>

Locale?는 후속 로직에서 null인 경우에 대한 처리를 계속 해줘야하므로 Locale로 처리하는 것을 권장드립니다.

 

Q3. ThemeService Riverpod 변환

아래 내용을 참고해 주세요.

final themeServiceProvider =
    NotifierProvider<ThemeService, AppTheme>(ThemeService.new);

class ThemeService extends Notifier<AppTheme> {
  @override
  AppTheme build() => LightTheme();

  /// 테마 변경
  void toggleTheme() {
    state = state.brightness == Brightness.light ? DarkTheme() : LightTheme();
  }

  /// Material ThemeData 커스텀
  ThemeData get themeData {
    return ThemeData(
      /// Scaffold
      scaffoldBackgroundColor: state.color.surface,

      /// AppBar
      appBarTheme: AppBarTheme(
        backgroundColor: state.color.surface,
        elevation: 0,
        centerTitle: false,
        iconTheme: IconThemeData(
          color: state.color.text,
        ),
        titleTextStyle: state.typo.headline2.copyWith(
          color: state.color.text,
        ),
      ),

      /// BottomSheet
      bottomSheetTheme: const BottomSheetThemeData(
        backgroundColor: Colors.transparent,
        constraints: BoxConstraints(
          maxWidth: Breakpoints.bottomSheet,
        ),
      ),
    );
  }
}

extension ThemeServiceExt on WidgetRef {
  ThemeService get themeService => watch(themeServiceProvider.notifier);
  AppTheme get theme => watch(themeServiceProvider);
  AppColor get color => theme.color;
  AppDeco get deco => theme.deco;
  AppTypo get typo => theme.typo;
}

감사합니다 :)

Link님의 프로필 이미지
Link
질문자

너무 너무 감사드립니다.

riverpod Full 버전을 올려주셔서 정말 많은 도움이 되었습니다.

BaseViewModel , BaseViewState 구현 부분을 이해하는데 어려움이 있지만 계속 보면서 학습하겠습니다.

DevStory님의 프로필 이미지
DevStory
지식공유자

기존 Provider 버전에서 구현한 View 공통 로직을 유사하게 구현하기 위해 BaseViewModel과 BaseViewState를 만들었지만, 코드에 정답은 없기 때문에 참고만 해주세요 :)

Link님의 프로필 이미지
Link

작성한 질문수

질문하기