どうも、ちょげ(@chogetarou)です。
Sliderの操作する部分であるつまみに枠線をつける方法を紹介します。
方法

Sliderのつまみに枠線をつけるには、SliderComponentShapeのカスタムクラスを使います。
まず、SliderComponentShapeのクラスを作ります。(テンプレみたいなものです)
class CircleThumbShape extends SliderComponentShape {
final double thumbRadius;
const CircleThumbShape({
this.thumbRadius = 10.0, //サイズ
});
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return Size.fromRadius(thumbRadius);
}
@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}) {
//つまみの描画
}
}
次に、通常のつまみ用と枠線用のPaintクラスを用意します。
class CircleThumbShape extends SliderComponentShape {
final double thumbRadius;
const CircleThumbShape({
this.thumbRadius = 10.0,
});
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return Size.fromRadius(thumbRadius);
}
@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;
//通常のつまみ用
final fillPaint = Paint()
..color = sliderTheme.thumbColor! //つまみの色
..style = PaintingStyle.fill;
//枠線用
final borderPaint = Paint()
..color = Colors.pink //枠線の色
..style = PaintingStyle.stroke
..strokeWidth = 2; //枠線の太さ
}
}
そして、用意したPaintクラスを描画します。
class CircleThumbShape extends SliderComponentShape {
final double thumbRadius;
const CircleThumbShape({
this.thumbRadius = 10.0,
});
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return Size.fromRadius(thumbRadius);
}
@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;
final fillPaint = Paint()
..color = sliderTheme.thumbColor!
..style = PaintingStyle.fill;
final borderPaint = Paint()
..color = Colors.pink
..style = PaintingStyle.stroke
..strokeWidth = 2;
canvas.drawCircle(center, thumbRadius, fillPaint); //通常のつまみの描画
canvas.drawCircle(center, thumbRadius, borderPaint); //枠線の描画
}
}
最後に、SliderThemeDataの引数「thumbShape」に用意したクラスを指定します。
SliderTheme(
data: SliderThemeData(
thumbShape: CircleThumbShape(),
),
child: Slider(
value: _value,
onChanged: (newValue) {
setState(() {
_value = newValue;
});
},
),
),
SliderComponentShapeを使うことで、Sliderのつまみに枠線をつけることが出来ます。
使用例

以下は、使用例です。
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double _value = 0.5;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Center(
child: SliderTheme(
data: SliderThemeData(
thumbShape: CircleThumbShape(),
),
child: Slider(
value: _value,
onChanged: (newValue) {
setState(() {
_value = newValue;
});
},
),
),
),
),
);
}
}
class CircleThumbShape extends SliderComponentShape {
final double thumbRadius;
const CircleThumbShape({
this.thumbRadius = 10.0,
});
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return Size.fromRadius(thumbRadius);
}
@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;
final fillPaint = Paint()
..color = sliderTheme.thumbColor!
..style = PaintingStyle.fill;
final borderPaint = Paint()
..color = Colors.pink
..style = PaintingStyle.stroke
..strokeWidth = 2;
canvas.drawCircle(center, thumbRadius, fillPaint);
canvas.drawCircle(center, thumbRadius, borderPaint);
}
}
コメント