Skip to content

Instantly share code, notes, and snippets.

@jogboms
Created August 1, 2022 11:39
Show Gist options
  • Save jogboms/109302ccb4d8a76e328352fe980ba9ca to your computer and use it in GitHub Desktop.
Save jogboms/109302ccb4d8a76e328352fe980ba9ca to your computer and use it in GitHub Desktop.
Simple switch assessment - Refactor
// AFTER: Added this for `lerpDouble`
import 'dart:ui';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const SwitchView(),
);
}
}
class SwitchView extends StatefulWidget {
const SwitchView({Key? key}) : super(key: key);
@override
State<SwitchView> createState() => _SwitchViewState();
}
class _SwitchViewState extends State<SwitchView> {
bool on = true;
void toggleSwitch(bool newState) {
setState(
() {
on = newState;
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: MySwitch(
value: on,
onChange: toggleSwitch,
)),
],
),
);
}
}
class MySwitch extends StatefulWidget {
const MySwitch({
Key? key,
required this.value,
required this.onChange,
this.onColor = const Color(0xffFFC559),
this.offColor = const Color(0xffA6B5F5),
this.thumbColor = const Color(0xffffffff),
}) : super(key: key);
final bool value;
final Color onColor;
final Color offColor;
final Color thumbColor;
final Function(bool) onChange;
@override
State<MySwitch> createState() => _MySwitchState();
}
class _MySwitchState extends State<MySwitch>
with SingleTickerProviderStateMixin {
late AnimationController animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 400),
//userd to set initial vale
value: widget.value ? 1 : 0,
);
late Animation<Color?> color;
late Animation<double?> postion;
// Animation animation = Animation();
@override
initState() {
color = ColorTween(
begin: Colors.grey,
end: Colors.blue,
).animate(animationController);
// BEFORE
// postion = Tween<double>(begin: 10, end: 40).animate(CurvedAnimation(
// AFTER
postion = Tween<double>(begin: 0, end: 1).animate(CurvedAnimation(
parent: animationController,
curve: Curves.easeIn,
reverseCurve: Curves.decelerate,
));
color = ColorTween(begin: widget.offColor, end: widget.onColor)
.animate(CurvedAnimation(
parent: animationController,
curve: Curves.decelerate,
reverseCurve: Curves.decelerate,
));
// .animate(animationController);
super.initState();
}
@override
void didUpdateWidget(MySwitch oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.value != widget.value) {
animateToValue();
}
}
animateToValue() {
setState(() {
widget.value
? animationController.forward()
: animationController.reverse();
});
}
@override
Widget build(BuildContext context) {
return Center(
child: AnimatedBuilder(
animation: animationController,
builder: (context, _) {
return GestureDetector(
onTap: () => widget.onChange(!widget.value),
child: CustomPaint(
painter: SwitchPaint(color.value!, postion.value!),
// BEFORE
// child: const SizedBox(
// height: 20,
// width: 50,
// ),
// AFTER
child: const SizedBox(
height: 200,
width: 500,
),
),
);
}),
);
}
}
class SwitchPaint extends CustomPainter {
final Color backgroundColor;
final double position;
SwitchPaint(this.backgroundColor, this.position);
@override
void paint(Canvas canvas, Size size) {
final bodyPaint = Paint()..color = backgroundColor;
final circlePaint = Paint()..color = Colors.white;
// BEFORE
// canvas.drawRRect(
// RRect.fromLTRBR(
// 0,
// 0,
// size.width,
// size.height,
// const Radius.circular(15),
// ),
// bodyPaint,
// );
// final circleRadius = size.height / 2;
// canvas.drawCircle(
// Offset(position, circleRadius),
// //for slight padding
// circleRadius - 1,
// circlePaint,
// );
// AFTER
final circleRadius = size.height / 2;
final trackRect = RRect.fromLTRBR(
0,
0,
size.width,
size.height,
Radius.circular(circleRadius),
);
canvas.drawRRect(
trackRect,
bodyPaint,
);
canvas.drawCircle(
Offset(
lerpDouble(trackRect.left + circleRadius, trackRect.right - circleRadius, position)!,
circleRadius,
),
circleRadius - circleRadius * .125,
circlePaint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment