[Flutter] fluent_ui로

쉬운 목차

개요


fluent_ui는 네이티브 Windows 앱을 개발할 때 사용할 수 있는 사용자 인터페이스입니다.

Flutter에서 사용할 수 있도록 라이브러리 형태로 구현되어 있습니다.

pub.dev에 게시되며 수많은 위젯을 지원합니다.


출처: 공식 사이트 https://bdlukaa.github.io/fluent_ui/

그 아래 이번 포스팅에서 구현할 내용은 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를 구현할 수 있습니다.