Skip to content

Instantly share code, notes, and snippets.

@faustobdls
Last active December 9, 2023 00:13
Show Gist options
  • Save faustobdls/2c08dd8f04fea0e5c5497af8876cea6b to your computer and use it in GitHub Desktop.
Save faustobdls/2c08dd8f04fea0e5c5497af8876cea6b to your computer and use it in GitHub Desktop.
TimeLine
// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TimelineLineWidget(
position: TimelineLineStatus.init,
first: Text("1"),
middle: [
Text("Oi"),
Text("eu sou goku!"),
],
),
TimelineLineWidget(
first: Text("2"),
middle: [
Text("Oi"),
Text("eu sou goku!"),
],
),
TimelineLineWidget(
first: Text("3"),
middle: [
Text("Oi"),
Text("eu sou goku!"),
],
),
TimelineLineWidget(
position: TimelineLineStatus.last,
first: Text("4"),
middle: [
Text("Oi"),
Text("eu sou goku!"),
],
),
],
),
),
);
}
}
class TimelineLineWidget extends StatelessWidget {
final TimelineLineStatus position;
final Widget? first;
final List<Widget> middle;
final Widget? last;
const TimelineLineWidget({
super.key,
this.first,
this.middle = const [],
this.last,
this.position = TimelineLineStatus.middle,
});
int genarateFlex(int initialFlex) {
int resultFlex = initialFlex;
if (first == null) resultFlex++;
if (last == null) resultFlex++;
return resultFlex;
}
@override
Widget build(BuildContext context) {
return Row(
children: [
if (first != null) ...{
Flexible(
flex: 1,
child: AspectRatio(
aspectRatio: 1,
child: CustomPaint(
painter: TimelimeStatusDefault(
lineStatus: position,
),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: CircleAvatar(
backgroundColor: Colors.blue,
child: CircleAvatar(
backgroundColor: Colors.white,
child: first,
),
),
),
),
),
),
},
Expanded(
flex: genarateFlex(3),
child: Column(
children: [
...middle,
],
),
),
if (last != null) ...{
Flexible(
flex: 1,
child: AspectRatio(
aspectRatio: 1,
child: last,
),
),
},
],
);
}
}
enum TimelineLineStatus {
init(false, true),
middle(true, true),
last(false, false);
final bool completeLine;
final bool hasInit;
const TimelineLineStatus(this.completeLine, this.hasInit);
}
class TimelimeStatusDefault extends CustomPainter {
final int stroke;
final TimelineLineStatus lineStatus;
TimelimeStatusDefault({
this.stroke = 10,
this.lineStatus = TimelineLineStatus.middle,
});
@override
void paint(Canvas canvas, Size size) {
double completePoint = (lineStatus.completeLine) ? 0 : size.height / 2;
Rect line = (lineStatus.hasInit)
? Rect.fromLTRB(
(size.width / 2) - (stroke / 2),
completePoint,
(size.width / 2) + (stroke / 2),
size.height,
)
: Rect.fromLTRB(
(size.width / 2) - (stroke / 2),
0,
(size.width / 2) + (stroke / 2),
completePoint,
);
Paint lineFill = Paint()..color = Colors.blue;
canvas.drawRect(line, lineFill);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment