[Flutter] Ui : 오류 SnackBar

Comely·2024년 11월 16일

Flutter

목록 보기
15/26

1. Freezed : class HomeUiEvent

import 'package:freezed_annotation/freezed_annotation.dart';

part 'home_ui_event.freezed.dart';


abstract class HomeUiEvent<T> with _$HomeUiEvent<T> {
  const factory HomeUiEvent.showSnackBar(String message) = ShowSnackBar;
}

2. HomeViewModel

  1. StreamController 생성
  final _eventController = StreamController<HomeUiEvent>();
  1. 에러 message를 _eventController에 전달
error: (message) {
        _eventController.add(HomeUiEvent.showSnackBar(message));
      },

HomeViewModel 전체코드

class HomeViewModel with ChangeNotifier {
  final GetPhotosUseCase getPhotosUseCase;

  HomeState _state = HomeState([], false);

  HomeState get state => _state;

  final _eventController = StreamController<HomeUiEvent>();

  Stream<HomeUiEvent> get eventStream => _eventController.stream;

  HomeViewModel(this.getPhotosUseCase);

  Future<void> fetch(String query) async {
    _state = state.copyWith(isLoading: true);
    notifyListeners();

    final Result<List<Photo>> result = await getPhotosUseCase(query);
    
    result.when(
      success: (photos) {
        _state = state.copyWith(photos: photos);
        notifyListeners();
      },
      error: (message) {
        _eventController.add(HomeUiEvent.showSnackBar(message));
      },
    );
    _state = state.copyWith(isLoading: false);
    notifyListeners();
  }
}

3. HomeScreen

_subscription = viewModel.eventStream.listen((event) {

initState()에 eventStream.listen을 실행합니다.
StreamSubscription 타입의 _subscription에 저장합니다.
(event)는 HomeUiEvent 타입으로 반환됩니다.

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final _controller = TextEditingController();
  StreamSubscription? _subscription;

  
  void initState() {
    super.initState();

    Future.microtask(() {
      final viewModel = context.read<HomeViewModel>();
      //StreamSubscription 타입
      _subscription = viewModel.eventStream.listen((event) {
        event.when(showSnackBar: (message) {
          final snackBar = SnackBar(content: Text(message));
          ScaffoldMessenger.of(context).showSnackBar(snackBar);
        });
      });
    });
  }

  
  void dispose() {
    _subscription?.cancel();
    _controller.dispose();
    super.dispose();
  }
profile
App, Web Developer

0개의 댓글