skip to Main Content

I have this widget with a slider and a ruler:

slider and 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:

expected result

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


  1. Instead of the Column, use Stack 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 widget

    Stack(
       children: [
         Slider(),
         MeasuredSize(),
       ]
    )
              
    Login or Signup to reply.
  2. I don’t have a direct answer to your question, but I can recommend you a grate package for UI Elements like that.

    Syncfusion

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search