Flutter时间选择滑块插件time_seek_slider的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter时间选择滑块插件time_seek_slider的使用

特性

  • 设置可用时间段(固定时间段、开始时间、结束时间)
  • 设置每个区段的宽度
  • 选择区段的时间(例如:10秒、30秒、1分钟、10分钟、1小时、3小时、12小时、24小时)
  • 选择主区段和次区段的颜色
  • 选择时间文本颜色
  • 在中心线上显示当前时间
  • 添加事件层覆盖,设置高度/颜色/时间段
  • 拖动或点击更改选定的日期时间
  • 接收时间变化事件
  • 接收拖动时间事件

开始使用

pubspec.yaml 文件中添加依赖:

dependencies:
  time_seek_slider: ^0.0.6

然后导入包:

import 'package:time_seek_slider/time_seek_slider.dart';

使用方法

简单创建一个 TimeSeekSlider 小部件,并传递所需的参数。可以在 /example 文件夹中添加更多示例。

基本用法

DateTime _selectedTime = DateTime(2024,4,28,15,30);

TimeSeekSlider(
  selectedTime: _selectedTime,
  onChangedSelectedTime: (time) {
    setState(() {
      _selectedTime = time;
    });
  },
),

固定时间段

如果要设置固定的可用时间段,可以将 fixedTerm 设置为 true

DateTime _from = DateTime(2024,4,28,0,0);
DateTime _to = DateTime(2024,4,29,0,0);
DateTime _selectedTime = DateTime(2024,4,28,15,30);

TimeSeekSlider(
  fixedTerm: true,
  from: _from,
  to: _to,
  selectedTime: _selectedTime,
  onChangedSelectedTime: (time) {
    setState(() {
      _selectedTime = time;
    });
  },
),

参数

参数名 必填/可选 类型 描述
selectedTime 必填 DateTime 选定的时间
fixedTerm 可选 bool 是否设置固定的可用时间段
from 可选 DateTime 固定时间段的开始时间
to 可选 DateTime 固定时间段的结束时间
sectionTime 可选 int 每个区段的时间长度
sectionWidth 可选 int 区段的宽度(像素)
timeTextColor 可选 Color 时间文本的颜色
sectionColorPrimery 可选 Color 主区段的颜色
sectionColorSecondary 可选 Color 次区段的颜色
centerLineColor 可选 Color 中心线(当前时间线)的颜色
showCurrentTime 可选 ShowCurrentTime 是否在中心线上显示当前时间
currentTimeTextColor 可选 Color 当前时间文本的颜色
currentTimeTextBackgroundColor 可选 Color 当前时间文本的背景颜色
events 可选 List<TimeEvent>? 显示在滑块上的事件信息

事件

事件名 必填/可选 描述
onChangedSelectedTime 必填 当点击条形图或拖动结束时触发
onChangingSelectedTime 可选 当拖动条形图时触发

完整示例

以下是一个完整的示例代码,展示了如何使用 time_seek_slider 插件。

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:time_seek_slider/time_seek_slider.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'TimeSeekSlider demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'TimeSeekSlider Package demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _isPlaying = false;
  DateTime _selectedTime = DateTime(2024,6,1,13,30);
  DateTime _selectingTime = DateTime(2024,6,1,13,30);
  final DateTime _from = DateTime(2024,6,1,12,0);
  final DateTime _to = DateTime(2024,6,1,14,0);
  int _sectionTime = TimeSeekSlider.sectionHour;

  final formatter = DateFormat('yyyy-MM-dd HH:mm:ss');

  [@override](/user/override)
  void initState() {
    super.initState();
    _startTimer();
  }

  void _startTimer() {
    Timer.periodic(const Duration(seconds: 1), (timer) {
      if (_isPlaying) {
        setState(() {
          if (_sectionTime < TimeSeekSlider.sectionMinute) {
            _selectedTime = _selectedTime.add(const Duration(seconds: 1));
          } else if (_sectionTime < TimeSeekSlider.sectionHour) {
            _selectedTime = _selectedTime.add(const Duration(seconds: 10));
          } else if (_sectionTime < TimeSeekSlider.section3Hours) {
            _selectedTime = _selectedTime.add(const Duration(minutes: 10));
          } else if (_sectionTime < TimeSeekSlider.section12Hours) {
            _selectedTime = _selectedTime.add(const Duration(minutes: 30));
          } else {
            _selectedTime = _selectedTime.add(const Duration(hours: 1));
          }
        });
      }
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    List<TimePeriod> timePeriods0 = [];
    for(int i=0; i < 10; i++) {
      timePeriods0.add(TimePeriod(
          DateTime(2024, 6, 1,13,00,0).add(Duration(minutes: 40*i)),
          DateTime(2024, 6, 1,13,30,0).add(Duration(minutes: 40*i))
      ));
    }

    List<TimePeriod> timePeriods1 = [];
    for(int i=0; i < 100; i++) {
      timePeriods1.add(TimePeriod(
          DateTime(2024, 6, 1,13,00,0).add(Duration(minutes: 10*i)),
          DateTime(2024, 6, 1,13,05,0).add(Duration(minutes: 10*i))
      ));
    }

    List<TimePeriod> timePeriods2 = [];
    for(int i=0; i < 100; i++) {
      timePeriods2.add(TimePeriod(
          DateTime(2024, 6, 1,13,00,0).add(Duration(minutes: 10*i)),
          DateTime(2024, 6, 1,13,00,0).add(Duration(minutes: 10*i))
      ));
    }

    List<TimeEvent> timeEvents = [];
    timeEvents.add(TimeEvent(20, Colors.yellow, timePeriods0));
    timeEvents.add(TimeEvent(10, Colors.green, timePeriods1));
    timeEvents.add(TimeEvent(70, Colors.black, timePeriods2));

    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text('Selected : ${formatter.format(_selectedTime)}'),
              Text('Dragging : ${formatter.format(_selectingTime)}'),
              SizedBox(
                height: 80,
                child: Container(
                  decoration: BoxDecoration(
                    color: const Color(0x00000000),
                    border: Border.all(
                      color: Colors.blue[900]!,
                      width: 1.0,
                    ),
                  ),
                  child: TimeSeekSlider(
                    fixedTerm: true,
                    from: _from,
                    to: _to,
                    selectedTime: _selectedTime,
                    sectionTime: _sectionTime,
                    sectionWidth: 100,
                    timeTextColor: Colors.indigo,
                    sectionColorPrimery: Colors.blue[50],
                    sectionColorSecondary: Colors.blue[100],
                    centerLineColor: Colors.blueAccent,
                    showCurrentTime: ShowCurrentTime.showDuringDragging,
                    currentTimeTextColor: Colors.white,
                    currentTimeTextBackgroundColor: Colors.blue,
                    events: timeEvents,
                    onChangingSelectedTime: (time) {
                      setState(() {
                        _selectingTime = time;
                      });
                    },
                    onChangedSelectedTime: (time) {
                      setState(() {
                        _selectedTime = time;
                      });
                    },
                  ),
                ),
              ),
              const SizedBox(height: 10,),
              SectionTimeChoice(
                onSelectionChanged: (selection) {
                  setState(() {
                    _sectionTime = selection;
                  });
                },
              ),
              ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _isPlaying = !_isPlaying;
                    });
                  },
                  child: Icon(_isPlaying ? Icons.stop : Icons.play_arrow)
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class SectionTimeChoice extends StatefulWidget {
  const SectionTimeChoice({super.key, this.onSelectionChanged});

  final Function(int)? onSelectionChanged;

  [@override](/user/override)
  State<SectionTimeChoice> createState() => _SectionTimeChoiceState();
}

class _SectionTimeChoiceState extends State<SectionTimeChoice> {
  int selectedRecordType = TimeSeekSlider.sectionHour;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return SegmentedButton<int>(
      segments: const <ButtonSegment<int>>[
        ButtonSegment<int>(
          value: TimeSeekSlider.section24Hours,
          label: Text('24h'),
        ),
        ButtonSegment<int>(
          value: TimeSeekSlider.section12Hours,
          label: Text('12h'),
        ),
        ButtonSegment<int>(
          value: TimeSeekSlider.section3Hours,
          label: Text('3h'),
        ),
        ButtonSegment<int>(
          value: TimeSeekSlider.sectionHour,
          label: Text('1h'),
        ),
        ButtonSegment<int>(
          value: TimeSeekSlider.section10Minute,
          label: Text('10m'),
        ),
        ButtonSegment<int>(
          value: TimeSeekSlider.sectionMinute,
          label: Text('1m'),
        ),
        ButtonSegment<int>(
          value: TimeSeekSlider.section30Seconds,
          label: Text('30s'),
        ),
        ButtonSegment<int>(
          value: TimeSeekSlider.section10Seconds,
          label: Text('10s'),
        ),
      ],
      selected: <int>{selectedRecordType},
      showSelectedIcon: false,
      onSelectionChanged: (Set<int> newSelection) {
        setState(() {
          selectedRecordType = newSelection.first;
        });
        widget.onSelectionChanged!(selectedRecordType);
      },
    );
  }
}

更多关于Flutter时间选择滑块插件time_seek_slider的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter时间选择滑块插件time_seek_slider的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用time_seek_slider插件的一个示例代码案例。time_seek_slider是一个用于时间选择的滑块插件,非常适合需要用户在一定时间范围内进行选择的场景。

首先,确保你已经在pubspec.yaml文件中添加了time_seek_slider依赖:

dependencies:
  flutter:
    sdk: flutter
  time_seek_slider: ^x.y.z  # 请将x.y.z替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,在你的Dart文件中,你可以按照以下方式使用TimeSeekSlider

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

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

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

class TimeSeekSliderDemo extends StatefulWidget {
  @override
  _TimeSeekSliderDemoState createState() => _TimeSeekSliderDemoState();
}

class _TimeSeekSliderDemoState extends State<TimeSeekSliderDemo> {
  DateTime? startTime;
  DateTime? endTime;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Time Seek Slider Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Selected Time Range:',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            TimeSeekSlider(
              initialStartTime: DateTime.now().subtract(Duration(hours: 24)),
              initialEndTime: DateTime.now(),
              minDuration: Duration(minutes: 15),
              maxDuration: Duration(hours: 24),
              interval: Duration(minutes: 1),
              onChanged: (DateTime? newStartTime, DateTime? newEndTime) {
                setState(() {
                  startTime = newStartTime;
                  endTime = newEndTime;
                });
              },
              onChangedEnd: (DateTime? newStartTime, DateTime? newEndTime) {
                print('Final selected range: $newStartTime - $newEndTime');
              },
              decoration: TimeSeekSliderDecoration(
                sliderColor: Colors.blue,
                activeTrackColor: Colors.lightBlue,
                inactiveTrackColor: Colors.grey,
                thumbColor: Colors.blueAccent,
                thumbShape: RoundSliderThumbShape(enabledThumbRadius: 12.0),
                overlayShape: RoundSliderOverlayShape(overlayRadius: 24.0),
              ),
            ),
            SizedBox(height: 20),
            if (startTime != null && endTime != null)
              Text(
                'Start: ${startTime!.toLocal().toString().split(' ')[1]} - End: ${endTime!.toLocal().toString().split(' ')[1]}',
                style: TextStyle(fontSize: 18),
              ),
          ],
        ),
      ),
    );
  }
}

在这个示例中:

  1. TimeSeekSlider被用于选择时间范围。
  2. initialStartTimeinitialEndTime分别设置了初始的开始和结束时间。
  3. minDurationmaxDuration分别设置了最小和最大的时间范围间隔。
  4. interval设置了滑块可以调整的最小时间间隔。
  5. onChanged回调在用户拖动滑块时触发,更新选择的开始和结束时间。
  6. onChangedEnd回调在用户完成选择后触发,可以用于处理最终选择的结果。
  7. decoration参数允许自定义滑块的外观,比如颜色、形状等。

这样,你就可以在你的Flutter应用中集成并使用time_seek_slider插件来选择时间范围了。

回到顶部