Horizontal Time Picker In Flutter

Horizontal Time Picker In Flutter :

Screenshot :

Horizontal Time Picker In Flutter

Widget Package :
– horizontal_time_picker.dart
– time_picker_util.dart
– time_widget.dart

horizontal_time_picker.dart

library horizontal_time_picker;
import 'package:flutter/material.dart';

import 'time_picker_util.dart';
import 'time_widget.dart';

typedef DateSelectionCallBack = void Function(DateTime dateTime);

class HorizontalTimePicker extends StatefulWidget {
  final int startTimeInHour;
  final int endTimeInHour;
  final DateTime dateForTime;
  final int timeIntervalInMinutes;
  final double height;
  final TextStyle timeTextStyle;
  final TextStyle selectedTimeTextStyle;
  final DateSelectionCallBack onTimeSelected;
  final DateSelectionCallBack onTimeUnSelected;
  final Decoration defaultDecoration;
  final Decoration selectedDecoration;
  final Decoration disabledDecoration;
  final List<DateTime> initialSelectedDates;
  final ScrollController scrollController;
  final double spacingBetweenDates;
  final EdgeInsetsGeometry padding;
  final int maxSelectedDateCount;
  final bool showDisabled;

  HorizontalTimePicker({
    Key key,
    this.height = 100,
    this.timeIntervalInMinutes = 15,
    @required this.startTimeInHour,
    @required this.endTimeInHour,
    @required this.dateForTime,
    this.scrollController,
    this.onTimeSelected,
    this.onTimeUnSelected,
    this.maxSelectedDateCount = 1,
    this.timeTextStyle,
    this.selectedTimeTextStyle,
    this.defaultDecoration,
    this.selectedDecoration,
    this.disabledDecoration,
    this.initialSelectedDates,
    this.spacingBetweenDates = 8.0,
    this.showDisabled = true,
    this.padding = const EdgeInsets.all(12.0),
  })  : assert(startTimeInHour != null),
        assert(dateForTime != null),
        assert(endTimeInHour != null),
        assert(
          endTimeInHour == startTimeInHour || startTimeInHour < endTimeInHour,
        ),
        super(key: key);

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

class TimeUnit {
  int _hour;
  int _minute;
  String _time;

  TimeUnit(this._hour, this._minute);

  int get hour => _hour;

  set hour(int value) {
    _hour = value;
  }

  String get time =>
      (_hour < 10 ? '0' : '') +
      _hour.toString() +
      ':' +
      (_minute < 10 ? '0' : '') +
      _minute.toString();

  int get minute => _minute;

  set minute(int value) {
    _minute = value;
  }
}

class _HorizontalTimePickerState extends State<HorizontalTimePicker> {
  final List<TimeUnit> allDateTimeSlots = [];
  List<TimeUnit> selectedDateTimeSlots = [];

  @override
  void initState() {
    super.initState();
    allDateTimeSlots.addAll(getDateTimeSlotList(
        widget.startTimeInHour,
        widget.endTimeInHour,
        widget.timeIntervalInMinutes,
        widget.dateForTime));
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: widget.height,
      child: Center(
        child: ListView.builder(
          controller: widget.scrollController ?? ScrollController(),
          scrollDirection: Axis.horizontal,
          itemCount: allDateTimeSlots.length,
          itemBuilder: (context, index) {
            final timeSlotIterated = allDateTimeSlots[index];
            if (!widget.showDisabled &&
                isTimeSlotDisabled(widget.dateForTime, timeSlotIterated)) {
              return Container();
            }
            return Row(
              children: <Widget>[
                TimeWidget(
                  key: Key(timeSlotIterated._time),
                  padding: widget.padding,
                  isSelected: isTimeSlotSelected(
                      selectedDateTimeSlots, timeSlotIterated),
                  isDisabled:
                      isTimeSlotDisabled(widget.dateForTime, timeSlotIterated),
                  date: widget.dateForTime,
                  timeUnit: timeSlotIterated,
                  timeTextStyle: widget.timeTextStyle,
                  selectedTimeTextStyle: widget.selectedTimeTextStyle,
                  defaultDecoration: widget.defaultDecoration,
                  selectedDecoration: widget.selectedDecoration,
                  disabledDecoration: widget.disabledDecoration,
                  onTap: () {
                    if (!selectedDateTimeSlots.contains(timeSlotIterated)) {
                      if (widget.maxSelectedDateCount == 1 &&
                          selectedDateTimeSlots.length == 1) {
                        selectedDateTimeSlots.clear();
                      }

                      selectedDateTimeSlots.add(timeSlotIterated);
                      if (widget.onTimeSelected != null) {
                        widget.onTimeSelected(DateTime(
                            widget.dateForTime.year,
                            widget.dateForTime.month,
                            widget.dateForTime.day,
                            timeSlotIterated.hour,
                            timeSlotIterated.minute,
                            0,
                            0,
                            0));
                      }
                    } else {
                      final isRemoved =
                          selectedDateTimeSlots.remove(timeSlotIterated);
                      if (isRemoved && widget.onTimeUnSelected != null) {
                        widget.onTimeUnSelected(DateTime(
                            widget.dateForTime.year,
                            widget.dateForTime.month,
                            widget.dateForTime.day,
                            timeSlotIterated.hour,
                            timeSlotIterated.minute,
                            0,
                            0,
                            0));
                      }
                    }
                    setState(() {
                      selectedDateTimeSlots = selectedDateTimeSlots;
                    });
                  },
                ),
                SizedBox(width: widget.spacingBetweenDates),
              ],
            );
          },
        ),
      ),
    );
  }
}

time_picker_util.dart

import 'horizontal_time_picker.dart';

List<TimeUnit> getDateTimeSlotList(int startTimeInHour, int endTimeInHour,
    int timeIntervalInMinutes, DateTime dateForTime) {
  List<TimeUnit> timeSlots = [];
  for (int i = startTimeInHour; i < endTimeInHour; i++) {
    int intervalDerived = 0;
    while (intervalDerived < 60) {
      timeSlots.add(TimeUnit(i, intervalDerived));
      intervalDerived = intervalDerived + timeIntervalInMinutes;
    }
  }
  return timeSlots;
}

isTimeSlotDisabled(DateTime dateForTime, TimeUnit timeSlot) {
  DateTime selectedDateTime = DateTime(dateForTime.year, dateForTime.month,
      dateForTime.day, timeSlot.hour, timeSlot.minute, 0, 0, 0);
  if (selectedDateTime.isBefore(DateTime.now())) {
    return true;
  }
  return false;
}

isTimeSlotSelected(
    List<TimeUnit> selectedDateTimeSlots, TimeUnit timeSlotIterated) {
  if (selectedDateTimeSlots.isEmpty) return false;
  bool found = false;
  selectedDateTimeSlots.forEach((timeSlot) {
    if (timeSlot.hour == timeSlotIterated.hour &&
        timeSlot.minute == timeSlotIterated.minute) {
      found = true;
    }
  });

  return found;
}

time_widget.dart

import 'package:flutter/material.dart';

import 'horizontal_time_picker.dart';

class AppColors {
  static const Color primaryElement = Color.fromARGB(255, 255, 255, 255);
}

class Borders {
  static const BorderSide primaryBorder = BorderSide(
    color: Color.fromARGB(255, 229, 229, 229),
    width: 1,
    style: BorderStyle.solid,
  );
}

class Radii {
  static const BorderRadiusGeometry k3pxRadius =
      BorderRadius.all(Radius.circular(5));
}

class TimeWidget extends StatelessWidget {
  final DateTime date;
  final TimeUnit timeUnit;
  final TextStyle timeTextStyle;
  final TextStyle selectedTimeTextStyle;
  final VoidCallback onTap;
  final VoidCallback onLongTap;
  final Decoration defaultDecoration;
  final Decoration selectedDecoration;
  final Decoration disabledDecoration;
  final bool isSelected;
  final bool isDisabled;
  final EdgeInsetsGeometry padding;

  TimeWidget({
    Key key,
    @required this.date,
    @required this.timeUnit,
    this.onTap,
    this.onLongTap,
    this.isSelected = false,
    this.isDisabled = false,
    this.timeTextStyle,
    this.selectedTimeTextStyle,
    this.defaultDecoration = const BoxDecoration(
      color: AppColors.primaryElement,
      border: Border.fromBorderSide(Borders.primaryBorder),
      borderRadius: Radii.k3pxRadius,
    ),
    this.selectedDecoration = const BoxDecoration(
      color: Colors.black87,
      border: Border.fromBorderSide(Borders.primaryBorder),
      borderRadius: Radii.k3pxRadius,
    ),
    this.disabledDecoration = const BoxDecoration(
      color: Colors.black26,
      border: Border.fromBorderSide(Borders.primaryBorder),
      borderRadius: Radii.k3pxRadius,
    ),
    this.padding,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    Decoration decoration = defaultDecoration;
    TextStyle timeStyle = timeTextStyle;
    if (isSelected) {
      timeStyle = selectedTimeTextStyle;
      decoration = selectedDecoration;
    } else if (isDisabled) {
      decoration = disabledDecoration;
    }
    return GestureDetector(
      onTap: isDisabled ? null : onTap,
      onLongPress: isDisabled ? null : onLongTap,
      child: Container(
        decoration: decoration,
        child: Padding(
          padding: padding,
          child: Text(
            timeUnit.time,
            textAlign: TextAlign.left,
            style: timeStyle,
          ),
        ),
      ),
    );
  }
}

main.dart

import 'package:flutter/material.dart';
import 'widget/horizontal_time_picker.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Horizontal Time Picker Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Horizontal Time Picker Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: HorizontalTimePicker(
          key: UniqueKey(),
          startTimeInHour: 9,
          endTimeInHour: 24,
          dateForTime: DateTime.now(),
          selectedTimeTextStyle: TextStyle(
            color: Colors.white,
            fontFamily: "Helvetica Neue",
            fontWeight: FontWeight.w300,
            fontSize: 16,
            height: 1.0,
          ),
          timeTextStyle: TextStyle(
            color: Colors.black,
            fontFamily: "Helvetica Neue",
            fontWeight: FontWeight.w300,
            fontSize: 16,
            height: 1.0,
          ),
          defaultDecoration: const BoxDecoration(
            color: Colors.white,
            border: Border.fromBorderSide(BorderSide(
              color: Color.fromARGB(255, 151, 151, 151),
              width: 1,
              style: BorderStyle.solid,
            )),
            borderRadius: BorderRadius.all(Radius.circular(5)),
          ),
          selectedDecoration: const BoxDecoration(
            color: Colors.black,
            border: Border.fromBorderSide(BorderSide(
              color: Color.fromARGB(255, 151, 151, 151),
              width: 1,
              style: BorderStyle.solid,
            )),
            borderRadius: BorderRadius.all(Radius.circular(5)),
          ),
          disabledDecoration: const BoxDecoration(
            color: Colors.black26,
            border: Border.fromBorderSide(BorderSide(
              color: Color.fromARGB(255, 151, 151, 151),
              width: 1,
              style: BorderStyle.solid,
            )),
            borderRadius: BorderRadius.all(Radius.circular(5)),
          ),
          showDisabled: true,
        ));
  }
}

The flutter tutorial  is a website that bring you the latest and amazing resources of code. All the languages codes are included in this website. The languages like flutter, android, java,kotlin etc.with the help of this languages any user can develop the beautiful application

For more information about Flutter. visit www.fluttertutorial.in