728x90
pubspec.yaml
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
/// 아래 2개 추가
syncfusion_flutter_datepicker: ^19.2.60
fluttertoast: ^8.0.3
- 추가해야 하는 플러그인 : syncfusion_flutter_datepicker, fluttertoast
- 추가 후 pub get 명령어로 플러그인 추가하기
DatePeriodPicker.dart
import 'package:common/common.dart';
import 'package:common/style.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datepicker/datepicker.dart';
/// 날짜 선택 위젯 (시작일, 종료일)
class DatePeriodPicker extends StatefulWidget {
/// 날짜 상태 변경 시
final Function(String? onValue)? onStartDateChanged;
final Function(String? onValue)? onEndDateChanged;
DatePeriodPicker({this.onStartDateChanged, this.onEndDateChanged});
@override
_DatePeriodPickerState createState() => _DatePeriodPickerState();
}
class _DatePeriodPickerState extends State<DatePeriodPicker> {
DateTime? startDate = DateTime.now();
DateTime? endDate = DateTime.now();
var isAllDay = true;
var controller = DateRangePickerController();
Widget searchBox(
String? title,
Widget child,
) {
return Row(
children: [
Expanded(
flex: 1,
child: Container(
alignment: Alignment.center,
child: Text('${title ?? ''}',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: CustomColor.dark,
),
),
),
),
Expanded(
flex: 3,
child: Container(
child: child,
),
),
SizedBox(width: 10,),
],
);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
flex: 1,
child: Container(
child: searchBox('시작일: ', DateInputButton(
Formatter.date('yyyy-MM-dd', startDate),
onTap: () => getDate(),
disabled: startDate == null || isAllDay,
),)
),
),
Expanded(
flex: 1,
child: Container(
child: searchBox('종료일: ',
DateInputButton(
Formatter.date('yyyy-MM-dd', endDate),
onTap: () => getDate(),
disabled: endDate == null || isAllDay,
),
)
),
),
],
);
}
Future getDate() async {
return showDialog(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
/// 달력 팝업창
content: SizedBox(
width: 500,
height: 300,
child: SfDateRangePicker(
selectionMode: DateRangePickerSelectionMode.range,
maxDate: DateTime.now(),
controller: controller,
),
),
actions: [
/// 달력 팝업창 하단 버튼
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('취소'),
),
TextButton(
onPressed: () {
var dateRange = controller.selectedRange;
if (dateRange == null ||
dateRange.startDate == null ||
dateRange.endDate == null) {
showToast('날짜를 올바르게 선택해주세요.');
} else {
setState(() {
isAllDay = false;
startDate = dateRange.startDate;
endDate = dateRange.endDate;
});
widget.onStartDateChanged
?.call(Formatter.date('yyyy-MM-dd', startDate));
widget.onEndDateChanged
?.call(Formatter.date('yyyy-MM-dd', endDate));
Navigator.pop(context);
}
},
child: Text('확인'),
),
],
),
);
}
}
/// 날짜 버튼
class DateInputButton extends StatelessWidget {
final String text;
final bool disabled;
final Function()? onTap;
DateInputButton(this.text, {this.disabled = false, this.onTap});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
width: 150,
height: 40,
padding: EdgeInsets.symmetric(horizontal: 15),
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
side: BorderSide(
color: CustomColor.lightGrey2,
width: 2,
),
borderRadius: BorderRadius.all(
Radius.circular(5),
),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
text,
style: TextStyle(color: CustomColor.dark),
),
Icon(Icons.calendar_today_outlined),
],
),
),
);
}
}
common.dart
import 'package:diaconn_aps_control/common/style.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
/// 날짜 포맷
class Formatter {
/*
Format Pattern Result
-------------- -------
'yyyy.MM.dd G 'at' HH:mm:ss vvvv' 1996.07.10 AD at 15:08:56 Pacific Time
'EEE, MMM d, ''yy' Wed, Jul 10, '96
'h:mm a' 12:08 PM
'hh 'o''clock' a, zzzz' 12 o'clock PM, Pacific Daylight Time
'K:mm a, vvv' 0:00 PM, PT
'yyyyy.MMMMM.dd GGG hh:mm aaa' 01996.July.10 AD 12:08 PM
*/
static String date(String pattern, date) {
try {
late DateTime dateTime;
if (date is DateTime) {
dateTime = date;
}else if(date is String){
if(date.length == 14){
String dateFirst = date.substring(0,8);
String dateSecond = date.substring(8,14);
dateTime = DateTime.parse('$dateFirst $dateSecond');
}else{
dateTime = DateTime.parse(date);
}
}
return DateFormat(pattern).format(dateTime);
} on FormatException catch (e) {
print('Formatter.date(pattern, date <== 여기문제) 제대로 된 날짜형식이 아닙니다.');
throw e;
}
}
static String currentDate(String pattern) {
return DateFormat(pattern).format(DateTime.now());
}
}
/// 미니 알림창
Future<void> showToast(String message) async {
await Fluttertoast.showToast(
msg: message,
backgroundColor: CustomColor.background,
);
}
styles.dart
import 'package:flutter/material.dart';
/// 사용자 정의 컬러
class CustomColor {
/// Dark
static const Color dark = Color(0xff020203);
/// Blue
static const Color lightBlue = Color(0xff6EC7C5);
static const Color lightBlue2 = Color(0xff81D3F9);
static const Color neonBlue = Color(0xff20c5e7);
/// Orange
static const Color lightOrange = Color(0xffFBD29C);
static const Color lightOrange2 = Color(0xffE4A24A);
/// Grey
static const Color lightGrey = Color(0xffF2F2F2);
static const Color lightGrey2 = Color(0xffE2E2E2);
static const Color lightGrey3 = Color(0xff666672);
static const Color lightGrey4 = Color(0xffC2C2C2);
static const Color background = Color(0xff313b48);
/// White
static const Color white = Color(0xFFFFFFFF);
static const Color white2 = Color(0xfff5f5f5);
/// Red
static const Color red = Color(0xFFC62828);
static const Color disabled = Color(0xff6e7f92);
}
실행 결과
- 검색 조건의 UI 틀은 DatePeriodPicker.dart 코드에서 Column 부분을 수정하면 된다.
'개발자 랩실 > 플러터 (Flutter)' 카테고리의 다른 글
[Flutter] cmdline-tools component is missing (0) | 2022.02.17 |
---|---|
[Flutter] The expression has a type of ‘void’ so its value can’t be used. (0) | 2022.02.16 |
Flutter 위젯 ExpansionTile (0) | 2022.01.22 |
A value of type ‘Object?’ can’t be assigned to a variable of type ‘LayoutType?’. (0) | 2022.01.17 |
Flutter에서 화면 이동 - Navigator (0) | 2022.01.13 |
댓글