I have this widget with a slider and a ruler:
how can I make the start and the end of the ruler align itself with the beginning and end of the slider?
Here is my code, I tried to put the slider inside a column and a row after it.
The expected result would be something like this:
Also, I am trying to mimic the ruler scale with a short width container and putting it inside a column to center aling the text with the scale.
class RulerWidget extends StatefulWidget {
const RulerWidget({super.key});
@override
State<RulerWidget> createState() => _RulerWidgetState();
}
class _RulerWidgetState extends State<RulerWidget> {
double _width = 0;
double _value = 1;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 8),
child: Column(
children: [
Align(
child: SizedBox(
width: _width + 48,
child: Slider(
thumbColor: primaryColor,
activeColor: primaryColor,
min: 1,
max: 9,
divisions: 8,
label: '${_value.round()}km',
value: _value,
onChanged: (value) {
setState(() {
_value = value;
});
},
),
),
),
MeasuredSize(
onChange: (size) => setState(() => _width = size.width),
child: SizedBox(
width: 300,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Container(
color: mediumGrey.withOpacity(0.6),
width: 2,
height: 7,
),
const SizedBox(height: 4),
const Text(
'1km',
style: TextStyle(color: mediumGrey, fontSize: 10),
),
],
),
Column(
children: [
Container(
color: mediumGrey.withOpacity(0.6),
width: 2,
height: 7,
),
const SizedBox(height: 4),
const Text(
'2km',
style: TextStyle(
color: Colors.transparent,
fontSize: 10,
),
),
],
),
Column(
children: [
Container(
color: mediumGrey.withOpacity(0.6),
width: 2,
height: 7,
),
const SizedBox(height: 4),
const Text(
'3km',
style: TextStyle(color: mediumGrey, fontSize: 10),
),
],
),
Column(
children: [
Container(
color: mediumGrey.withOpacity(0.6),
width: 2,
height: 7,
),
const SizedBox(height: 4),
const Text(
'4km',
style: TextStyle(
color: Colors.transparent,
fontSize: 10,
),
),
],
),
Column(
children: [
Container(
color: mediumGrey.withOpacity(0.6),
width: 2,
height: 7,
),
const SizedBox(height: 4),
const Text(
'5km',
style: TextStyle(color: mediumGrey, fontSize: 10),
),
],
),
Column(
children: [
Container(
color: mediumGrey.withOpacity(0.6),
width: 2,
height: 7,
),
const SizedBox(height: 4),
const Text(
'1km',
style: TextStyle(
color: Colors.transparent,
fontSize: 10,
),
),
],
),
Column(
children: [
Container(
color: mediumGrey.withOpacity(0.6),
width: 2,
height: 7,
),
const SizedBox(height: 4),
const Text(
'7km',
style: TextStyle(color: mediumGrey, fontSize: 10),
),
],
),
Column(
children: [
Container(
color: mediumGrey.withOpacity(0.6),
width: 2,
height: 7,
),
const SizedBox(height: 4),
const Text(
'1km',
style: TextStyle(
color: Colors.transparent,
fontSize: 10,
),
),
],
),
Column(
children: [
Container(
color: mediumGrey.withOpacity(0.6),
width: 2,
height: 7,
),
const SizedBox(height: 4),
const Text(
'9km',
style: TextStyle(color: mediumGrey, fontSize: 10),
),
],
),
],
),
),
),
],
),
);
}
}
2
Answers
Instead of the
Column
, useStack
to wrap the slider and measured-size widgets to overlap them.To meet your requirements, you may need to wrap the measured-size widget with
Positioned
widgetI don’t have a direct answer to your question, but I can recommend you a grate package for UI Elements like that.
Syncfusion