Created
July 27, 2020 10:22
-
-
Save richard457/e73e3dac80cfd7cd5ce682482141d6e1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
class CustomSliderThumbCircle extends SliderComponentShape { | |
final double thumbRadius; | |
final int min; | |
final int max; | |
const CustomSliderThumbCircle({ | |
@required this.thumbRadius, | |
this.min = 0, | |
this.max = 10, | |
}); | |
@override | |
Size getPreferredSize(bool isEnabled, bool isDiscrete) { | |
return Size.fromRadius(thumbRadius); | |
} | |
@override | |
void paint( | |
PaintingContext context, | |
Offset center, { | |
Animation<double> activationAnimation, | |
Animation<double> enableAnimation, | |
bool isDiscrete, | |
TextPainter labelPainter, | |
RenderBox parentBox, | |
SliderThemeData sliderTheme, | |
TextDirection textDirection, | |
double value, | |
double textScaleFactor, | |
Size sizeWithOverflow, | |
}) { | |
final Canvas canvas = context.canvas; | |
final paint = Paint() | |
..color = Colors.white | |
..style = PaintingStyle.fill; | |
TextSpan span = new TextSpan( | |
style: new TextStyle( | |
fontSize: thumbRadius * .8, | |
fontWeight: FontWeight.w700, | |
color: sliderTheme.thumbColor, | |
), | |
text: getValue(value), | |
); | |
TextPainter tp = new TextPainter( | |
text: span, | |
textAlign: TextAlign.center, | |
textDirection: TextDirection.ltr); | |
tp.layout(); | |
Offset textCenter = | |
Offset(center.dx - (tp.width / 2), center.dy - (tp.height / 2)); | |
canvas.drawCircle(center, thumbRadius * .9, paint); | |
tp.paint(canvas, textCenter); | |
} | |
String getValue(double value) { | |
return ((max * value).round()).toString(); | |
} | |
} | |
// the widget | |
class SliderWidget extends StatefulWidget { | |
final double sliderHeight; | |
final int min; | |
final int max; | |
final fullWidth; | |
SliderWidget( | |
{this.sliderHeight = 48, | |
this.max = 10, | |
this.min = 0, | |
this.fullWidth = false}); | |
@override | |
_SliderWidgetState createState() => _SliderWidgetState(); | |
} | |
class _SliderWidgetState extends State<SliderWidget> { | |
double _value = 0; | |
@override | |
Widget build(BuildContext context) { | |
double paddingFactor = .2; | |
if (this.widget.fullWidth) paddingFactor = .3; | |
return Container( | |
width: this.widget.fullWidth | |
? double.infinity | |
: (this.widget.sliderHeight) * 5.5, | |
height: (this.widget.sliderHeight), | |
decoration: new BoxDecoration( | |
borderRadius: new BorderRadius.all( | |
Radius.circular((this.widget.sliderHeight * .3)), | |
), | |
gradient: new LinearGradient( | |
colors: [ | |
const Color(0xFF00c6ff), | |
const Color(0xFF0072ff), | |
], | |
begin: const FractionalOffset(0.0, 0.0), | |
end: const FractionalOffset(1.0, 1.00), | |
stops: [0.0, 1.0], | |
tileMode: TileMode.clamp), | |
), | |
child: Padding( | |
padding: EdgeInsets.fromLTRB(this.widget.sliderHeight * paddingFactor, | |
2, this.widget.sliderHeight * paddingFactor, 2), | |
child: Row( | |
children: <Widget>[ | |
Text( | |
'${this.widget.min}', | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
fontSize: this.widget.sliderHeight * .3, | |
fontWeight: FontWeight.w700, | |
color: Colors.white, | |
), | |
), | |
SizedBox( | |
width: this.widget.sliderHeight * .1, | |
), | |
Expanded( | |
child: Center( | |
child: SliderTheme( | |
data: SliderTheme.of(context).copyWith( | |
activeTrackColor: Colors.white.withOpacity(1), | |
inactiveTrackColor: Colors.white.withOpacity(.5), | |
trackHeight: 4.0, | |
thumbShape: CustomSliderThumbCircle( | |
thumbRadius: this.widget.sliderHeight * .4, | |
min: this.widget.min, | |
max: this.widget.max, | |
), | |
overlayColor: Colors.white.withOpacity(.4), | |
//valueIndicatorColor: Colors.white, | |
activeTickMarkColor: Colors.white, | |
inactiveTickMarkColor: Colors.red.withOpacity(.7), | |
), | |
child: Slider( | |
value: _value, | |
onChanged: (value) { | |
setState(() { | |
_value = value; | |
}); | |
}), | |
), | |
), | |
), | |
SizedBox( | |
width: this.widget.sliderHeight * .1, | |
), | |
Text( | |
'${this.widget.max}', | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
fontSize: this.widget.sliderHeight * .3, | |
fontWeight: FontWeight.w700, | |
color: Colors.white, | |
), | |
), | |
], | |
), | |
), | |
); | |
} | |
} | |
final Color darkBlue = Color.fromARGB(255, 18, 32, 47); | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue), | |
debugShowCheckedModeBanner: false, | |
home: Scaffold( | |
body: Center( | |
child: SliderWidget(), | |
), | |
), | |
); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment