flutter로 로컬스토리지를 사용하는 앱을 개발하며 datepicker 오픈 패키지를 커스텀해서 사용하는 과정에서 문제가 있었다.
https://github.com/sivaprasadnk/SimpleMonthYearPicker
기존의 CupertinoDatePicker는 일을 없애고 년과 월 옵션만 넣도록 커스텀이 안돼서 위의 오픈소스 패키지를 사용하게 되었다.
내가 구현하고자 한 기능은 datepicker를 통해 원하는 날짜를 선택하면 해당 달에 기록된 일기를 모두 조회해주는 간단한 기능이었다.
drift와 getit패키지를 사용하였고 해당부분 데이터를 조회하는 쿼리는 아래와 같다.
Stream<List<Thank>> watchMonthSelectedThanks(DateTime date){
final query = select(thanks);
query.where((tbl) => tbl.date.year.equals(date.year) & tbl.date.month.equals(date.month));
query.orderBy([(tbl) => OrderingTerm(expression: tbl.date)]);
return query.watch();
}
본론으로 들어가서, 해당 부분을 구현하며 파악한 문제상황은 이렇다.
1) datepicker를 클릭하면 현재 날짜(8월)이 디폴트로 선택되어있음. => 어딘가에서 초기값이 설정 되어있음
2) datepicker에서 다른 날짜(9월, 10월 등)를 선택하고 창을 닫으면 해당 날짜의 데이터들이 잘 조회됨 => 쿼리에는 문제가 없음
3) 다른 날짜의 데이터들이 잘 조회된 상태에서 다시 datepicker를 열면 해당날짜로 유지되어있는 것이 아니라 초기값인 8월로 선택된 날짜가 돌아가있는 것이 문제이다. (예를들어 10월을 골라 10월의 데이터들을 조회하고 다시 열면 10월이 선택되어있어야 한다.)
이 부분을 해결하기 위해서 우선 showMonthYearPickerDialog에 newSelectedDate변수를 추가하고 해당값을 datepicker 내부에서 사용할 수 있도록 커스텀했다.
static Future<DateTime> showMonthYearPickerDialog({
required BuildContext context,
TextStyle? titleTextStyle,
TextStyle? yearTextStyle,
TextStyle? monthTextStyle,
Color? backgroundColor,
Color? selectionColor,
bool? barrierDismissible,
bool? disableFuture,
required DateTime newSelectedDate, //추가
}) async {
final ThemeData theme = Theme.of(context);
var primaryColor = selectionColor ?? theme.primaryColor;
var bgColor = backgroundColor ?? theme.scaffoldBackgroundColor;
// var textTheme = theme.textTheme;
/// to get current year
int selectedYear = newSelectedDate.year; //변경
// int selectedYear = DateTime.now().year;
/// to get index corresponding to current month (1- Jan, 2- Feb,..)
var selectedMonth = newSelectedDate.month; //변경
// var selectedMonth = DateTime.now().month;
그랬더니 이 함수를 사용하는 부분에서 초기값이 들어오지 않을 때가 문제인 상황이 발생했다.
그래서 이 함수가 사용되는 state 함수 내부에서 아래와 같은 구조로 이미 선택되어있는 날짜와 date picker를 통해 받아오는 날짜를 구분해서 관리할 수 있도록 구현했다.
late DateTime selectedDate;
late DateTime picked;
@override
void initState() {
super.initState();
selectedDate = DateTime.now();
picked = DateTime.now();
}
final monthTextStyle = TextStyle(
fontWeight: FontWeight.w600,
color: Colors.black54,
fontSize: 14.0,
);
Future<void> _selectDate(BuildContext context) async {
picked = await SimpleMonthYearPicker
.showMonthYearPickerDialog(
context: context,
titleTextStyle: monthTextStyle,
monthTextStyle: monthTextStyle,
yearTextStyle: monthTextStyle,
barrierDismissible: true,
disableFuture: true,
backgroundColor: DEEP_BEIGE,
selectionColor: PRIMARY_COLOR,
newSelectedDate: picked,
);
if( picked != null && picked != selectedDate){
setState(() {
selectedDate = DateTime(picked.year, picked.month);
});
}
}
이렇게 해당 이슈를 해결할 수 있었다.
'Flutter' 카테고리의 다른 글
토큰 재발급 요청이 중복으로 나가는 문제 - 요청 대기열 만들어 해결 (0) | 2024.02.06 |
---|---|
unable to boot the simulator. 해결방법 (0) | 2023.10.27 |
const Constructor (0) | 2023.08.16 |
Stateful, Stateless Widget LifeCycle (0) | 2023.08.16 |
flutter android배포시 build에러 : Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules jetified-kotlin-stdlib-1.8.10 (0) | 2023.08.08 |