timeline_editor 0.3.4 timeline_editor: ^0.3.4 copied to clipboard
A flutter wiidget to help you manage timelines like video timeline with tracks editable or not. with move, actions...
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:timeline_editor/timeline_editor.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
Duration box1Start = Duration.zero;
Duration box2Start = Duration(seconds: 120);
bool deleted = false;
double position = 0;
bool customTimeString = false;
StreamController<double> positionController;
Timer progressTimer;
double _trackHeight = 100;
AnimationController _controller;
Animation<double> _animation;
void updateBox1(Duration duration) {
if (box1Start + duration < Duration.zero) {
duration = -box1Start;
}
setState(() {
box1Start += duration;
});
}
void updateBox2(Duration duration) {
if (box2Start + duration < Duration.zero) {
duration = -box2Start;
}
setState(() {
box2Start += duration;
});
}
void positionUpdate(Timer timer) {
position += 0.350;
if (position > 300) position = 0;
positionController.add(position);
/* if (position + 0.1 < 300)
Timer(Duration(milliseconds: 100), () => positionUpdate());*/
}
@override
void initState() {
super.initState();
positionController = StreamController<double>.broadcast();
progressTimer = Timer.periodic(Duration(milliseconds: 350), positionUpdate);
_controller =
AnimationController(vsync: this, duration: Duration(seconds: 2));
_animation = Tween(begin: 100.0, end: 200.0).animate(_controller)
..addListener(() {
setState(() => _trackHeight = _animation.value);
});
positionUpdate(null);
}
@override
void dispose() {
progressTimer?.cancel();
positionController?.close();
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
List<TimelineEditorContinuousBox> boxesContinuous = [
TimelineEditorContinuousBox(
Duration(),
color: Colors.deepOrange,
child: const Image(image: const AssetImage('assets/image2.jpg')),
),
TimelineEditorContinuousBox(
box2Start,
menuEntries: [
PopupMenuItem<String>(child: Text('Delete'), value: 'deleted')
],
onMoved: updateBox2,
onSelectedMenuItem: (v) {
print('Selected: $v');
if (v == "deleted")
setState(() {
deleted = true;
});
},
onTap: (start, duration) =>
print('tapped for $start to ${start + duration}'),
color: Colors.black,
child: const Image(image: const AssetImage('assets/image.jpg')),
),
];
return MaterialApp(
darkTheme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: const Text('Timeline_editor example app'),
),
body: Column(
children: <Widget>[
Expanded(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('Timeline_editor example app'),
RaisedButton(
child: const Text('Change track height'),
onPressed: () =>
_controller.status == AnimationStatus.forward ||
_controller.status == AnimationStatus.completed
? _controller.reverse()
: _controller.forward(),
),
SwitchListTile(
title: Text('Custom time string'),
value: customTimeString,
onChanged: (value) =>
setState(() => customTimeString = value)),
],
))),
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: TimelineEditor(
timeWidgetExtent: customTimeString ? 100 : null,
timeWidgetBuilder: customTimeString
? (d, t) => Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
'${d.inSeconds}/${t.inSeconds}',
overflow: TextOverflow.ellipsis,
),
)
: null,
onPositionTap: (s) => position = s,
positionStream: positionController.stream,
countTracks: 2,
trackBuilder: (track, pps, duration) => track == 1
? TimelineEditorTrack(
defaultColor: Colors.green[700],
boxes: [
TimelineEditorBox(box1Start, Duration(seconds: 100),
onMoved: updateBox1,
color: Colors.blue,
onMovedEnd: () => print('end moved')),
TimelineEditorBox(
Duration(seconds: 157), Duration(seconds: 80)),
],
pixelsPerSeconds: pps,
duration: duration,
)
: TimelineEditorTrack.fromContinuous(
trackHeight: _trackHeight,
continuousBoxes:
deleted ? [boxesContinuous[0]] : boxesContinuous,
pixelsPerSeconds: pps,
duration: duration,
),
duration: Duration(seconds: 300),
)),
],
),
),
);
}
}