3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Flutter】table_calendarを使ったシンプルなアプリの作り方

Posted at

はじめに

この記事ではFlutterでカレンダーを表示するためのライブラリである
table_calendar を使った簡単なアプリの実装方法を説明します。

機能としてはカレンダー上で選択した日付の値を別途表示します。
この基本的な機能をベースにTodoアプリなどに応用して頂ければと思います。

開発環境

tools/library ver
MacBook Pro 11.6
Flutter 2.5.4
Dart 2.14.4
table_calendar 3.0.3

完成品とソースコード

完成品

完成品の仕様を説明します。
トップページは以下のような構成です。

  • 「Calendar Selected App」という Text ウィジェット
  • table_calendar ライブラリの TableCalendar ウィジェット
  • TableCalendar ウィジェットで選択した日付を表示する Textウィジェット

image.png

このアプリではページ遷移はありません。
ですのでFAB(FloatingActionButton)などのボタン類はありません。

todo:ここにスクショなど

ソースコード

  • pubspec.yaml
table_calendar: ^3.0.3
  • lib/main.dart

import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'table_calendar app',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: TopPage());
  }
}

class TopPage extends StatefulWidget {
  const TopPage({Key? key}) : super(key: key);

  @override
  _TopPageState createState() => _TopPageState();
}

class _TopPageState extends State<TopPage> {
  DateTime _selectedDay = DateTime.now();
  DateTime _focusedDay = DateTime.now();
  @override
  Widget build(BuildContext context) {
    double ui_height = MediaQuery.of(context).size.height;
    double ui_width = MediaQuery.of(context).size.width;

    return Scaffold(
      body: Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Center(
              child: Text(
                "Calendar Selected App",
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.w800),
              ),
            ),
            SizedBox(
              height: ui_height * 0.05,
            ),
            Center(
              child: Container(
                  width: ui_width * 0.9,
                  height: ui_height * 0.5,
                  child: TableCalendar(
                    headerVisible: false,
                    firstDay: DateTime.utc(1900, 10, 16),
                    lastDay: DateTime.utc(2030, 3, 14),
                    focusedDay: _focusedDay,
                    selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
                    onDaySelected: (selectedDay, focusedDay) {
                      setState(() {
                        _selectedDay = selectedDay;
                      });
                    },
                  )),
            ),
            SizedBox(
              height: ui_height * 0.045,
            ),
            Container(
              child: Text(
                "selected year : ${_selectedDay.year}",
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
              ),
            ),
            Container(
              child: Text(
                "selected month : ${_selectedDay.month}",
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
              ),
            ),
            Container(
              child: Text(
                "selected day : ${_selectedDay.day}",
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
              ),
            ),
          ],
        ),
      ),
    );
  }
}


ソースコード説明

本アプリでのtable_calendar の使い方を簡単に説明します。

まず table_calendarを利用するためにライブラリをimportします。


import 'package:table_calendar/table_calendar.dart';

次に選択している日付オブジェクトを用意します。
本アプリでは一旦アプリを開いた当日の DateTime オブジェクトにしています。


  DateTime _selectedDay = DateTime.now();
  DateTime _focusedDay = DateTime.now();

次に TableCalendar ウィジェットを用意します。


TableCalendar(
  headerVisible: false,
  firstDay: DateTime.utc(1900, 10, 16),
  lastDay: DateTime.utc(2030, 3, 14),
  focusedDay: _focusedDay,
  selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
  onDaySelected: (selectedDay, focusedDay) {
    setState(() {
      _selectedDay = selectedDay;
    });
  },
)

headerVisiblefalse にすることでヘッダーを非表示にします。
このプロパティはデフォルトで true なので必要に応じて設定してください。
今回はヘッダーが不要だったので false にしています。

firstDay プロパティはカレンダーで表示可能な最も古い日付を指定します。

lastDay プロパティはカレンダーで表示可能な将来の日付を指定します。

focusedDay では表示をする日付を DateTime オブジェクトで渡します。今回は _focusedDay で指定します。

selectedDayPredicate ではコールバック関数を受け取ります。
役割は「 true になった時に日付が変わったと判定する」というものです。ですので引数で受けた day と現在選択している
_selectedDay を比較して一致した場合に isSameDay() メソッドから true を受け取ります。

最後に onDaySelected プロパティでは selectedDayPredicatetrue になった際に
どのような処理を行うかを記述します。今回は _selectedDay を更新します。

また _selectedDay の値を表示に反映しているウィジェットは以下です。


Container(
  child: Text(
    "selected year : ${_selectedDay.year}",
    style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
  ),
),
Container(
  child: Text(
    "selected month : ${_selectedDay.month}",
    style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
  ),
),
Container(
  child: Text(
    "selected day : ${_selectedDay.day}",
    style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
  ),
),

表示に反映する _selectedDay を式内展開で Text ウィジェットに渡しています。

式内展開とは英語では「String interpolation」と呼ばれています。詳細は以下リンクをご参照ください。

まとめ

本記事では table_calendarTableCalendar ウィジェットを使った簡単なアプリの作り方を説明しました。
今回は選択した日付を表示するだけ、というシンプルなアプリでした。なので実仕様に落とし込む際にはこの実装方法を応用して頂ければと思います。

以上になります。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?