개요
fluent_ui는 네이티브 Windows 앱을 개발할 때 사용할 수 있는 사용자 인터페이스입니다.
Flutter에서 사용할 수 있도록 라이브러리 형태로 구현되어 있습니다.
pub.dev에 게시되며 수많은 위젯을 지원합니다.

그 아래 이번 포스팅에서 구현할 내용은 DatePicker 입니다.

위젯을 클릭하면 아래와 같이 날짜를 선택할 수 있는 시트가 배포됩니다.

화신
먼저 pubspec.yaml 파일을 열고 패키지를 추가합니다.
intl 최신 버전은 0.18.0으로 확인되었으나 fluent_ui 버전 4.4.0과 호환되지 않으니 하위 버전을 사용하세요.
dependencies:
flutter:
sdk: flutter
fluent_ui: ^4.4.0
intl: ^0.17.0
StatefulWidget을 사용하여 위젯을 만듭니다.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
fluent_ui를 사용하려면 다음 패키지를 가져옵니다.
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
Fluent_ui를 사용하여 DatePicker를 구현하고 있으므로 위젯을 생성하는 코드에 샘플 코드를 복사하여 붙여넣습니다.

import 'package:flutter/material.dart';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
DateTime? selected = DateTime.now();
@override
Widget build(BuildContext context) {
return DatePicker(
header: 'Pick a date',
selected: selected,
onChanged: (time) => setState(() => selected = time),
),
}
}
이렇게 쓰면 에러가 납니다.
DatePicker는 FluentApp이라는 위젯에 작성해야 합니다.
FluentApp의 Home 속성에 DatePicker를 넣어야 합니다.
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
DateTime? selected = DateTime.now();
@override
Widget build(BuildContext context) {
return FluentApp(
home: DatePicker(
header: '',
selected: selected,
onChanged: (time) => setState(() => selected = time),
)
);
}
}
이렇게 작성하시면 80% 완성입니다.
그러나 빌드 중에 또 다른 오류가 발생합니다.
여기에 localizationDelegates 및 supportedLocales 속성을 추가해야 합니다.
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
DateTime? selected = DateTime.now();
@override
Widget build(BuildContext context) {
return FluentApp(
localizationsDelegates: const (
FluentLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
),
supportedLocales: const (
Locale('en'),
Locale('kr'),
),
home: DatePicker(
header: '',
selected: selected,
onChanged: (time) => setState(() => selected = time),
)
);
}
}
이제 DatePicker에서 선택한 날짜를 Header 속성에 삽입합니다.
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
DateTime? selected = DateTime.now();
@override
Widget build(BuildContext context) {
return FluentApp(
localizationsDelegates: const (
FluentLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
),
supportedLocales: const (
Locale('en'),
Locale('kr'),
),
home: DatePicker(
header: selected!,
selected: selected,
onChanged: (time) => setState(() => selected = time),
)
);
}
}
헤더에서 selected를 0이 아닌 것으로 설정하고 붙여넣으면 2023년 3월 7일은 3/7/2023으로 나타납니다.
그러나 DatePicker의 순서는 월/일/년 순서입니다.
먼저 DatePicker의 날짜 순서를 년/월/일로 조정하는 로캘 속성을 작성합니다.
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
DateTime? selected = DateTime.now();
@override
Widget build(BuildContext context) {
return FluentApp(
localizationsDelegates: const (
FluentLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
),
supportedLocales: const (
Locale('en'),
Locale('kr'),
),
home: DatePicker(
locale: const Locale("ko"),
header: selected!,
selected: selected,
onChanged: (time) => setState(() => selected = time),
)
);
}
}
또한 dateFormatted 및 헤더의 날짜를 한국어 스타일로 변경하기 위해 날짜 형식을 지정하는 파서를 추가합니다.
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
DateTime? selected = DateTime.now();
String getFormattedDate(String dateString) {
DateTime date = DateFormat("M/d/yyyy").parse(dateString);
return DateFormat("yyyy년 MM월 dd일").format(date);
}
final dateFormatter = DateFormat.yMd(Intl.getCurrentLocale());
@override
Widget build(BuildContext context) {
return FluentApp(
localizationsDelegates: const (
FluentLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
),
supportedLocales: const (
Locale('en'),
Locale('kr'),
),
home: DatePicker(
locale: const Locale("ko"),
header: getFormattedDate(dateFormatter.format(selected!)),
selected: selected,
onChanged: (time) => setState(() => selected = time),
)
);
}
}
이렇게 DatePicker를 구현할 수 있습니다.

