position_seek_widget.dart 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import 'package:flutter/material.dart';
  2. class PositionSeekWidget extends StatefulWidget {
  3. final Duration currentPosition;
  4. final Duration duration;
  5. final Function(Duration) seekTo;
  6. const PositionSeekWidget({
  7. @required this.currentPosition,
  8. @required this.duration,
  9. @required this.seekTo,
  10. });
  11. @override
  12. _PositionSeekWidgetState createState() => _PositionSeekWidgetState();
  13. }
  14. class _PositionSeekWidgetState extends State<PositionSeekWidget> {
  15. Duration _visibleValue;
  16. bool listenOnlyUserInterraction = false;
  17. double get percent => widget.duration.inMilliseconds == 0
  18. ? 0
  19. : _visibleValue.inMilliseconds / widget.duration.inMilliseconds;
  20. @override
  21. void initState() {
  22. super.initState();
  23. _visibleValue = widget.currentPosition;
  24. }
  25. @override
  26. void didUpdateWidget(PositionSeekWidget oldWidget) {
  27. super.didUpdateWidget(oldWidget);
  28. if (!listenOnlyUserInterraction) {
  29. _visibleValue = widget.currentPosition;
  30. }
  31. }
  32. @override
  33. Widget build(BuildContext context) {
  34. return Padding(
  35. padding: EdgeInsets.only(left: 8.0, right: 8.0),
  36. child: Row(
  37. mainAxisAlignment: MainAxisAlignment.center,
  38. children: [
  39. SizedBox(
  40. width: 50,
  41. child: Text(
  42. durationToString(widget.currentPosition),
  43. style: Theme.of(context).textTheme.subtitle1,
  44. ),
  45. ),
  46. Expanded(
  47. child: Slider(
  48. min: 0,
  49. max: widget.duration.inMilliseconds.toDouble(),
  50. value: percent * widget.duration.inMilliseconds.toDouble(),
  51. onChangeEnd: (newValue) {
  52. setState(() {
  53. listenOnlyUserInterraction = false;
  54. widget.seekTo(_visibleValue);
  55. });
  56. },
  57. onChangeStart: (_) {
  58. setState(() {
  59. listenOnlyUserInterraction = true;
  60. });
  61. },
  62. onChanged: (newValue) {
  63. setState(() {
  64. final to = Duration(milliseconds: newValue.floor());
  65. _visibleValue = to;
  66. });
  67. },
  68. ),
  69. ),
  70. SizedBox(
  71. width: 50,
  72. child: Text(
  73. durationToString(widget.duration),
  74. style: Theme.of(context).textTheme.subtitle1,
  75. ),
  76. ),
  77. ],
  78. ),
  79. );
  80. }
  81. }
  82. String durationToString(Duration duration) {
  83. String twoDigits(int n) {
  84. if (n >= 10) return "$n";
  85. return "0$n";
  86. }
  87. String twoDigitMinutes =
  88. twoDigits(duration.inMinutes.remainder(Duration.minutesPerHour));
  89. String twoDigitSeconds =
  90. twoDigits(duration.inSeconds.remainder(Duration.secondsPerMinute));
  91. return "$twoDigitMinutes:$twoDigitSeconds";
  92. }