【Flutter】flutter_datetime_picker_plus を使って時間フィールドをなくした分:秒の時間ピッカーを作成しよう

image

はじめに

こんにちは。可茂IT塾のkiichiです。

今回は、flutter_datetime_picker_plusというパッケージを使って、時・分・秒が選択できるピッカーから、分・秒だけを選択できるピッカーにする方法を紹介します。

サンプルアプリ

この記事では、以下のサンプルアプリを解説します。

実装方法

開発環境

  • VSCode 1.88.1
  • Flutter 3.13.4
  • Dart 3.1.2

パッケージのインポート

pubspec.yamlに以下のパッケージを追加してください。

  flutter_datetime_picker_plus_plus: ^2.2.0 
  intl: ^0.19.0

intl は、DateFormat クラスを介して日付と時刻のフォーマットを行うために使用しています。

flutter_datetime_picker_plus は、Flutterアプリケーションで日付と時刻のピッカーを簡単に実装するために使用しています。

モデルコード

時間のフィールドをなくすために、CustomPickerクラスを作成します。CommonPickerModelクラスをextendsし、時間の選択や表示に必要なメソッドやプロパティをCustomPickerクラスに提供します。

import 'package:flutter_datetime_picker_plus_plus/flutter_datetime_picker_plus_plus.dart';

class CustomPicker extends CommonPickerModel {
  String digits(int value, int length) {
    return '$value'.padLeft(length, "0");
  }

  CustomPicker({DateTime? currentTime, super.locale}) {
    this.currentTime = currentTime ?? DateTime.now();
    setLeftIndex(this.currentTime.hour);
    setMiddleIndex(this.currentTime.minute);
    setRightIndex(this.currentTime.second);
  }

  
  String? leftStringAtIndex(int index) {
    if (index >= 0 && index < 24) {
      return digits(index, 2);
    } else {
      return null;
    }
  }

  
  String? middleStringAtIndex(int index) {
    if (index >= 0 && index < 60) {
      return digits(index, 2);
    } else {
      return null;
    }
  }

  
  String? rightStringAtIndex(int index) {
    if (index >= 0 && index < 60) {
      return digits(index, 2);
    } else {
      return null;
    }
  }

  
  String leftDivider() {
    return "";
  }

  
  String rightDivider() {
    return ":";
  }

  
  List<int> layoutProportions() {
    return [0, 1, 1];
  }

  
  DateTime finalTime() {
    return currentTime.isUtc
        ? DateTime.utc(currentTime.year, currentTime.month, currentTime.day,
            currentLeftIndex(), currentMiddleIndex(), currentRightIndex())
        : DateTime(currentTime.year, currentTime.month, currentTime.day,
            currentLeftIndex(), currentMiddleIndex(), currentRightIndex());
  }
}

上記のコードでは、以下5つの処理が行われています。

  1. コンストラクタ内で、初期化時に現在の時間を取得し、左側のインデックスには時、中央のインデックスには分、右側のインデックスには秒を設定する。
  2. leftStringAtIndexmiddleStringAtIndexrightStringAtIndex メソッドでは、各部分の文字列を返します。時、分、秒それぞれについて、指定されたインデックスに対応する文字列を生成する。
  3. leftDivider メソッドで時と分、 rightDivider メソッドで分と秒の間の区切り文字列を返す。この場合、時と分の間には区切り文字がなく、分と秒の間にコロンが使われる。
  4. layoutProportions メソッドで、ピッカー内の各部分のレイアウト比率を設定する。この場合、左側に時、中央に分、右側に秒が配置され、左側の比率が0になっているため、時間フィールドが表示されなくなる。
  5. finalTime メソッドでは、ユーザーが選択した時間を取得する。選択された時、分、秒を元に、DateTime オブジェクトを作成して返す。UTC時刻であるかどうかに応じて、DateTime オブジェクトが作成される。

全体コード

import 'package:example_code/CustomPicker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker_plus_plus/flutter_datetime_picker_plus_plus.dart';
import 'package:intl/intl.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late String _selectedTime;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Datetime Picker'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () {
                DatePicker.showPicker(context, showTitleActions: true,
                    onChanged: (date) {
                  print('change $date in time zone ' +
                      date.timeZoneOffset.inHours.toString());
                }, onConfirm: (time) {
                  print('confirm $time');
                  _selectedTime = DateFormat("HH-mm-ss").format(time);
                  print(_selectedTime);
                },
                  // ここでCustomPickerを使用している
                    pickerModel: CustomPicker(currentTime: DateTime.now()),
                    locale: LocaleType.en);
              },
              child: const Text(
                'show custom time picker',
              ),
            ),
          ],
        ),
      ),
    );
  }
}

上記のコードでは、CustomPicker.dart ファイルから CustomPicker クラスをインポートしています。 pickerModel オプションに CustomPicker を設定することで、時を選択するフィールドが表示されないCustomPickerを使用することができます。

さいごに

今回は、CustomPickerを作成して、時間ピッカーを分・秒だけ選択できるピッカーにする方法を紹介しましたが、「秒」の表記が不要な場合は、 showSecondsColumn オプションに false を設定することで表示させないようにすることができます。ぜひ、どちらの方法も試してみてください!

お知らせ

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More

タグ

Flutter (112)初心者向け (28)イベント (18)Google Apps Script (15)Nextjs (12)可茂IT塾 (9)Firebase (7)riverpod (6)React (6)ChatGPT (5)vscode (5)デザイン (5)新卒 (4)就活 (4)Figma (4)Dart (4)JavaScript (4)お知らせ (4)FlutterWeb (3)Prisma (3)NestJS (3)Slack (3)TypeScript (3)ワーケーション (3)インターン (3)設計 (2)線型計画法 (2)事例 (2)Git (2)Image (2)File (2)Material Design (2)画像 (2)iOS (2)アプリ開発 (2)React Hooks (2)tailwindcss (2)社会人 (2)大学生 (2)RSS (1)Google (1)Web (1)CodeRunner (1)個人開発 (1)Android (1)Unity (1)WebView (1)Twitter (1)フルリモート (1)TextScaler (1)textScaleFactor (1)学生向け (1)supabase (1)Java (1)Spring Boot (1)shell script (1)正規表現 (1)パワーポイント (1)趣味 (1)モンスターボール (1)CSS (1)SCSS (1)Cupertino (1)ListView (1)就活浪人 (1)既卒 (1)保守性 (1)iPad (1)シェアハウス (1)スクレイピング (1)PageView (1)画面遷移 (1)flutter_hooks (1)Gmail (1)GoogleWorkspace (1)ShaderMask (1)google map (1)Google Places API (1)GCPコンソール (1)Google_ML_Kit (1)Vercel (1)Google Domains (1)DeepLeaning (1)深層学習 (1)Google Colab (1)コード生成 (1)GitHub Copilot (1)オンラインオフィス (1)オブジェクト指向 (1)クラスの継承 (1)ポリモーフィズム (1)LINE (1)Bitcoin (1)bitFlyer (1)コミュニティー (1)文系エンジニア (1)Freezed (1)ヒーター (1)作業効率 (1) (1)permission_handler (1)flutter_local_notifications (1)markdown (1)GlobalKey (1)ValueKey (1)Key (1)アイコン (1)go_router (1)debug (1)datetime_picker (1)Apple Store Connect (1)FlutterGen (1)デバッグ (1)Widget Inspector (1)VRChat (1)API (1)検索機能 (1)Shader (1)Navigator (1)メール送信 (1)FlutterFlow (1)Firebase App Distribution (1)Fastlane (1)Dio (1)CustomClipper (1)ClipPath (1)カスタム認証 (1)アニメーション (1)Arduino (1)ESP32 (1)経験談 (1)フリーランス (1)mac (1)csv (1)docker (1)GithubActions (1)Dialog (1)BI (1)LifeHack (1)ショートカット (1)Chrome (1)高校生 (1)キャリア教育 (1)非同期処理 (1)生体認証 (1)BackdropFilter (1)レビュー (1)getAuth (1)Algolia (1)コンサルティング (1)Symbol (1)

お知らせ

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More