Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import 'dart:math' as math;
- import 'package:flutter/material.dart';
- import 'package:flutter/scheduler.dart';
- void main() => runApp(MyApp());
- class MyApp extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- debugShowCheckedModeBanner: false,
- title: 'Flutter Demo',
- theme: ThemeData(
- primarySwatch: Colors.blue,
- ),
- home: MyHomePage(title: 'Flutter Demo Home Page'),
- );
- }
- }
- class MyHomePage extends StatefulWidget {
- MyHomePage({Key key, this.title}) : super(key: key);
- final String title;
- @override
- _MyHomePageState createState() => _MyHomePageState();
- }
- class _MyHomePageState extends State<MyHomePage> {
- static var _items = [
- ["\$100M", "In research grants for scientific investigations"],
- ["1985", "In research grants for scientific investigations"],
- ["\$200M", "Simply dummy text of the printing and typesetting industry"],
- ["1995", "Contrary to popular belief, Lorem Ipsum is not simply random text"],
- ["\$100M", "In research grants for scientific investigations"],
- ["1985", "In research grants for scientific investigations"],
- ["\$200M", "Simply dummy text of the printing and typesetting industry"],
- ["1995", "Contrary to popular belief, Lorem Ipsum is not simply random text"],
- ["\$100M", "In research grants for scientific investigations"],
- ["1985", "In research grants for scientific investigations"],
- ["\$200M", "Simply dummy text of the printing and typesetting industry"],
- ["1995", "Contrary to popular belief, Lorem Ipsum is not simply random text"],
- ["\$100M", "In research grants for scientific investigations"],
- ["1985", "In research grants for scientific investigations"],
- ["\$200M", "Simply dummy text of the printing and typesetting industry"],
- ["1995", "Contrary to popular belief, Lorem Ipsum is not simply random text"],
- ["\$100M", "In research grants for scientific investigations"],
- ["1985", "In research grants for scientific investigations"],
- ["\$200M", "Simply dummy text of the printing and typesetting industry"],
- ["1995", "Contrary to popular belief, Lorem Ipsum is not simply random text"],
- ];
- List<TimeLineItem> items = [];
- List<Color> timeLineColors = [
- Colors.red,
- Colors.green,
- Colors.blue,
- Colors.orange,
- ];
- @override
- void initState() {
- super.initState();
- _items.asMap().forEach((i, item) {
- items.add(
- TimeLineItem(
- color: timeLineColors[i%timeLineColors.length],
- axisDirection: i.isEven ? AxisDirection.up : AxisDirection.down,
- text1: Text(
- item[0],
- textAlign: TextAlign.start,
- style: TextStyle(
- color: Color(0xFF454545),
- fontWeight: FontWeight.normal,
- fontSize: 21.0,
- fontFamily: 'RobotoMedium',
- ),
- ),
- text2: Text(
- item[1],
- textAlign: TextAlign.start,
- overflow: TextOverflow.ellipsis,
- maxLines: 3,
- style: TextStyle(
- color: Color(0xFF455454),
- fontWeight: FontWeight.normal,
- fontSize: 13.0,
- fontFamily: 'RobotoLight',
- ),
- ),
- ),
- );
- });
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text(widget.title),
- ),
- body: Container(
- margin: EdgeInsets.symmetric(vertical: 20.0),
- height: 130.0,
- child: TimeLineItems(
- items: items,
- ),
- ),
- );
- }
- }
- ///
- /// Timeline Widget
- ///
- class TimeLineItems extends StatefulWidget {
- TimeLineItems({
- Key key,
- this.width = 140.0,
- this.height = 50.0,
- this.spaceBetween = 15.0,
- this.items = const [],
- });
- final double width;
- final double height;
- final double spaceBetween;
- final List<TimeLineItem> items;
- @override
- TimeLineItemsState createState() {
- return TimeLineItemsState();
- }
- }
- class TimeLineItemsState extends State<TimeLineItems> {
- ScrollController _scrollController;
- @override
- void initState() {
- super.initState();
- }
- @override
- dispose() {
- _scrollController.dispose();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- _scrollController = new ScrollController(initialScrollOffset: 200);
- SchedulerBinding.instance.addPostFrameCallback((_) {
- _scrollController.animateTo(
- -10.0, duration: new Duration(seconds: 3), curve: Curves.ease);
- });
- return ListView.builder(
- scrollDirection: Axis.horizontal,
- itemCount: widget.items.length,
- controller: _scrollController,
- itemBuilder: (BuildContext ctxt, int index) {
- return Container(
- margin: EdgeInsets.only(top: widget.spaceBetween, right: widget.spaceBetween),
- child: Stack(
- children: <Widget>[
- Positioned(
- width: widget.width - 20,
- top: 0,
- left: 20,
- child: Container(
- alignment: Alignment.bottomLeft,
- child: widget.items[index].axisDirection == AxisDirection.down
- ? widget.items[index].text2
- : widget.items[index].text1,
- width: widget.width,
- height: widget.height - 5,
- ),
- ),
- Positioned(
- width: widget.width - 20,
- top: widget.height + 10,
- left: 20,
- child: Container(
- alignment: Alignment.topLeft,
- child: widget.items[index].axisDirection == AxisDirection.down
- ? widget.items[index].text1
- : widget.items[index].text2,
- width: widget.width,
- height: widget.height,
- ),
- ),
- CustomPaint(
- size: Size(widget.width, widget.height),
- painter: TimeLinePainter(
- widget.items[index].color,
- widget.width,
- widget.height,
- widget.items[index].axisDirection,
- ),
- ),
- ],
- ),
- );
- });
- }
- }
- ///
- /// Model
- ///
- class TimeLineItem {
- TimeLineItem({
- this.color = Colors.black,
- @required this.text1,
- @required this.text2,
- this.axisDirection = AxisDirection.up,
- });
- Color color;
- Text text1;
- Text text2;
- AxisDirection axisDirection;
- }
- ///
- /// Painter
- ///
- class TimeLinePainter extends CustomPainter {
- final Color color;
- final double width;
- final double height;
- final AxisDirection axis;
- TimeLinePainter(this.color, this.width, this.height, this.axis);
- @override
- void paint(Canvas canvas, Size size) {
- final Paint circle = Paint()
- ..color = color
- ..strokeWidth = 3.0
- ..strokeCap = StrokeCap.round
- ..style = PaintingStyle.stroke;
- canvas.drawArc(
- Rect.fromCircle(
- center: Offset(10, height),
- radius: 6.0,
- ),
- -math.pi / 2,
- 2 * math.pi,
- false,
- circle,
- );
- final Paint lineX = Paint()
- ..color = color
- ..style = PaintingStyle.fill;
- canvas.drawRect(
- Rect.fromLTWH(
- 15,
- height,
- width,
- 3.0,
- ),
- lineX,
- );
- final Paint lineY = Paint()
- ..color = color
- ..style = PaintingStyle.fill;
- canvas.drawRect(
- Rect.fromLTWH(
- 8,
- axis == AxisDirection.down ? height + 5 : height - 5,
- 3.0,
- axis == AxisDirection.down ? height : -height,
- ),
- lineY,
- );
- final Paint circleFill = Paint()
- ..color = color
- ..strokeWidth = 3.0
- ..strokeCap = StrokeCap.round
- ..style = PaintingStyle.fill;
- canvas.drawArc(
- Rect.fromCircle(
- center: Offset(10, axis == AxisDirection.down ? height * 2 + 5 : -5),
- radius: 6.0,
- ),
- -math.pi / 2,
- 2 * math.pi,
- false,
- circleFill,
- );
- canvas.translate(-50.0, 10.0);
- }
- @override
- bool shouldRepaint(TimeLinePainter old) => false;
- }
Add Comment
Please, Sign In to add comment