[앱개발] 예보 : 마음을 읽다.
[예보:마음을 읽는] 개인 리스트 화면 - 사용자가 Firesotre에 저장한 화면을 보여준다. [ MVVM ]
godofwisdom
2022. 4. 8. 20:49
개인화면 - 스크롤뷰
개인화면 - 리스트뷰
개인화면의 구성은 CustomScrollView 로 구성되어 개인통계/상세/피드리스트 위젯으로 구성 하였다.
화면에 대한 이벤트는
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:mind_weather/domain/model/weather_model.dart';
part 'weather_event.freezed.dart';
part 'weather_event.g.dart';
@freezed
class WeatherEvent with _$WeatherEvent {
const factory WeatherEvent.deleteWeather(WeatherModel weatherModel) =
DeleteWeather;
const factory WeatherEvent.geWeathers() = GetWeathers;
const factory WeatherEvent.getByIdWeathers(String uid) = GetByIdWeathers;
const factory WeatherEvent.getWeatherById(String uid) = GetWeatherById;
factory WeatherEvent.fromJson(Map<String, dynamic> json) =>
_$WeatherEventFromJson(json);
}
화면을 구성하는 ViewModel 은
import 'package:flutter/cupertino.dart';
import 'package:mind_weather/domain/model/weather_model.dart';
import 'package:mind_weather/domain/repository/weather_repository.dart';
import 'weather_event.dart';
import 'weather_state.dart';
/// 이벤트의 기능을 구현하는곳
class PersonListViewModel extends ChangeNotifier {
final WeatherRepository weatherRepository;
PersonListViewModel(this.weatherRepository) {
_getWeathers();
}
WeatherState _weatherState = WeatherState();
WeatherState get weatherState => _weatherState;
Future<void> onEvent(WeatherEvent event) async {
event.when(
geWeathers: _getWeathers,
getWeatherById: _getWeatherById,
getByIdWeathers: _getByIdWeathers,
deleteWeather: _deleteWeather);
}
Future<void> _deleteWeather(WeatherModel weatherModel) async {
await weatherRepository.deleteWeather(weatherModel);
await _getWeathers();
}
Future<void> _getWeathers() async {
List<WeatherModel>? weathers = await weatherRepository.getWeathers();
_weatherState = _weatherState.copyWith(weatherModels: weathers);
notifyListeners();
}
Future<void> _getWeatherById(String uid) async {
final weatherModel = await weatherRepository.getWeatherById(uid);
_weatherState = _weatherState.copyWith(weatherModel: weatherModel);
}
Future<void> _getByIdWeathers(String uid) async {
List<WeatherModel>? weathers = await weatherRepository.getByIdWeathers(uid);
_weatherState = _weatherState.copyWith(weatherModels: weathers);
notifyListeners();
}
}
그리고 ViewModel에서 WeatherState로 상태를 관리한다.
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:mind_weather/domain/model/weather_model.dart';
part 'weather_state.freezed.dart';
part 'weather_state.g.dart';
@freezed
class WeatherState with _$WeatherState {
@JsonSerializable(fieldRename: FieldRename.snake, explicitToJson: true)
const factory WeatherState({
WeatherModel? weatherModel,
List<WeatherModel>? weatherModels,
}) = _WeatherState;
factory WeatherState.fromJson(Map<String, dynamic> json) =>
_$WeatherStateFromJson(json);
}
ViewModel에서는 Repository를 의존성 주입하였고,
Firestore의 유틸은 아래와 같이 구현하였다.
Future<List<WeatherModel>?> getByIdWeathers(String uid) async {
final maps = await firestore
.collection(collectionName)
.where("user_uid", isEqualTo: uid)
.orderBy("time_stamp", descending: true)
.get();
return maps.docs.map((dataShot) {
WeatherModel model = WeatherModel.fromJson(dataShot.data());
model = model.copyWith(uid: dataShot.id);
return model;
}).toList();
}
Future<List<WeatherModel>?> getWeathers() async {
final maps = await firestore
.collection(collectionName)
.orderBy("time_stamp", descending: true)
.get();
return maps.docs.map((dataShot) {
WeatherModel model = WeatherModel.fromJson(dataShot.data());
model = model.copyWith(uid: dataShot.id);
return model;
}).toList();
}
Future<WeatherModel?> getWeatherById(String uid) async {
WeatherModel weatherModel = (await firestore
.collection(collectionName)
.doc(uid)
.get()) as WeatherModel;
return weatherModel;
}
현재 MVVM모델로 프로젝트를 구성중이고,
Presentation
ㄴ person_list
ㄴ component
ㄴ view_model
ㄴ person_list_screen.dart
형태로 구현하였다.