I am using Slider in Flutter for value selections but it needs to be customised as below :
Normally I can create default slider but how can I achieve this Thumbh UI on my slider? Thanks.
CodePudding user response:
The following would do the trick. You have to customize the
Here's a minimal reproducible example (Also, live demo on DartPad)
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double sliderValue = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.only(left: 24.0),
child: Text(
'Font Size',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
Theme(
data: Theme.of(context).copyWith(
sliderTheme: const SliderThemeData(
thumbShape: MySliderComponentShape(),
trackShape: SameHeightRoundedSliderTrackShape(),
trackHeight: 8,
),
),
child: Slider(
onChanged: (value) => setState(() => sliderValue = value),
value: sliderValue,
min: 0,
max: 2,
divisions: 2,
activeColor: const Color.fromARGB(255, 231, 231, 231),
inactiveColor: const Color.fromARGB(255, 231, 231, 231),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Padding(
padding: EdgeInsets.only(left: 24),
child: Text('Small', style: TextStyle(fontSize: 14)),
),
Text('Medium', style: TextStyle(fontSize: 14)),
Padding(
padding: EdgeInsets.only(right: 24),
child: Text('Large', style: TextStyle(fontSize: 14)),
),
],
)
],
),
),
);
}
}
class MySliderComponentShape extends SliderComponentShape {
const MySliderComponentShape();
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return const Size(34, 34);
}
@override
void paint(PaintingContext context, Offset center,
{required Animation<double> activationAnimation,
required Animation<double> enableAnimation,
required bool isDiscrete,
required TextPainter labelPainter,
required RenderBox parentBox,
required SliderThemeData sliderTheme,
required TextDirection textDirection,
required double value,
required double textScaleFactor,
required Size sizeWithOverflow}) {
final Canvas canvas = context.canvas;
canvas.drawShadow(
Path()
..addRRect(RRect.fromRectAndRadius(
Rect.fromCenter(center: center, width: 38, height: 34),
const Radius.circular(19),
)),
Colors.black,
5,
false);
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromCenter(center: center, width: 34, height: 34),
const Radius.circular(17),
),
Paint()..color = const Color.fromARGB(255, 252, 241, 216),
);
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromCenter(center: center, width: 26, height: 26),
const Radius.circular(13),
),
Paint()..color = const Color.fromARGB(255, 235, 151, 72),
);
}
}
class SameHeightRoundedSliderTrackShape extends RoundedRectSliderTrackShape {
const SameHeightRoundedSliderTrackShape();
@override
void paint(
PaintingContext context,
Offset offset, {
required RenderBox parentBox,
required SliderThemeData sliderTheme,
required Animation<double> enableAnimation,
required TextDirection textDirection,
required Offset thumbCenter,
bool isDiscrete = false,
bool isEnabled = false,
double additionalActiveTrackHeight = 0,
}) {
super.paint(
context,
offset,
parentBox: parentBox,
sliderTheme: sliderTheme,
enableAnimation: enableAnimation,
textDirection: textDirection,
thumbCenter: thumbCenter,
isDiscrete: isDiscrete,
isEnabled: isEnabled,
additionalActiveTrackHeight: additionalActiveTrackHeight,
);
}
}