custom_ruler 1.0.0 copy "custom_ruler: ^1.0.0" to clipboard
custom_ruler: ^1.0.0 copied to clipboard

A highly customizable ruler/scale widget for Flutter with support for horizontal and vertical orientations, snapping, and custom styling.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:custom_ruler/custom_ruler.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Ruler Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: const RulerDemoPage(),
    );
  }
}

class RulerDemoPage extends StatefulWidget {
  const RulerDemoPage({super.key});

  @override
  State<RulerDemoPage> createState() => _RulerDemoPageState();
}

class _RulerDemoPageState extends State<RulerDemoPage> {
  double _weightKg = 70.0;
  int _heightCm = 175;

  final GlobalKey<CustomRulerState> _weightRulerKey = GlobalKey();
  final GlobalKey<CustomRulerState> _heightRulerKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Custom Ruler Demo'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Weight Picker Section
            _buildSectionTitle('Weight Picker (Horizontal)'),
            const SizedBox(height: 8),
            Center(
              child: Text(
                '${_weightKg.toStringAsFixed(1)} kg',
                style: const TextStyle(
                  fontSize: 48,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
            const SizedBox(height: 16),
            SizedBox(
              height: 120,
              child: CustomRuler(
                key: _weightRulerKey,
                orientation: RulerOrientation.horizontal,
                minRange: 0,
                maxRange: 200,
                lineSpacing: 0.1,
                pixelSpacing: 9,
                initialValue: _weightKg,
                decimalPlaces: 0,
                rulerHeight: 120,
                pointerLength: 120,
                pointerThickness: 2,
                pointerColor: Colors.blue,
                barAlignment: BarAlignment.end,
                majorBarColor: Colors.grey.shade600,
                mediumBarColor: Colors.grey.shade400,
                minorBarColor: Colors.grey.shade300,
                labelColor: Colors.grey.shade500,
                onChange: (value) {
                  setState(() => _weightKg = value);
                },
              ),
            ),
            const SizedBox(height: 8),
            Center(
              child: ElevatedButton(
                onPressed: () {
                  _weightRulerKey.currentState?.scrollToValue(70.0);
                },
                child: const Text('Reset to 70 kg'),
              ),
            ),

            const SizedBox(height: 32),
            const Divider(),
            const SizedBox(height: 32),

            // Height Picker Section
            _buildSectionTitle('Height Picker (Vertical)'),
            const SizedBox(height: 16),
            Row(
              children: [
                Expanded(
                  child: Column(
                    children: [
                      Text(
                        '$_heightCm',
                        style: const TextStyle(
                          fontSize: 64,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      const Text(
                        'cm',
                        style: TextStyle(fontSize: 24, color: Colors.grey),
                      ),
                      const SizedBox(height: 16),
                      ElevatedButton(
                        onPressed: () {
                          _heightRulerKey.currentState?.scrollToValue(175);
                        },
                        child: const Text('Reset'),
                      ),
                    ],
                  ),
                ),
                SizedBox(
                  width: 120,
                  height: 300,
                  child: CustomRuler(
                    key: _heightRulerKey,
                    orientation: RulerOrientation.vertical,
                    barAlignment: BarAlignment.end,
                    alignmentPosition: AlignmentPosition.right,
                    minRange: 50,
                    maxRange: 250,
                    lineSpacing: 1,
                    pixelSpacing: 12,
                    initialValue: _heightCm.toDouble(),
                    rulerHeight: 100,
                    decimalPlaces: 0,
                    majorInterval: 10,
                    mediumInterval: 5,
                    majorBarColor: Colors.grey.shade600,
                    mediumBarColor: Colors.grey.shade400,
                    minorBarColor: Colors.grey.shade300,
                    labelColor: Colors.grey.shade500,
                    pointerColor: Colors.green,
                    onChange: (value) {
                      setState(() => _heightCm = value.round());
                    },
                  ),
                ),
              ],
            ),

            const SizedBox(height: 32),
            const Divider(),
            const SizedBox(height: 32),

            // Custom Styled Ruler
            _buildSectionTitle('Custom Styled Ruler'),
            const SizedBox(height: 16),
            SizedBox(
              height: 100,
              child: CustomRuler(
                orientation: RulerOrientation.horizontal,
                minRange: 0,
                maxRange: 10,
                lineSpacing: 0.1,
                pixelSpacing: 20,
                initialValue: 5,
                decimalPlaces: 1,
                rulerHeight: 100,
                pointerWidget: Container(
                  width: 3,
                  height: 80,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(2),
                    gradient: const LinearGradient(
                      colors: [Colors.purple, Colors.blue],
                      begin: Alignment.topCenter,
                      end: Alignment.bottomCenter,
                    ),
                  ),
                ),
                barAlignment: BarAlignment.center,
                majorBarColor: Colors.purple,
                mediumBarColor: Colors.purple.shade200,
                minorBarColor: Colors.purple.shade100,
                labelColor: Colors.purple,
                labelStyle: const TextStyle(
                  color: Colors.purple,
                  fontSize: 14,
                  fontWeight: FontWeight.bold,
                ),
                onChange: (value) {
                  // Handle change
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildSectionTitle(String title) {
    return Text(
      title,
      style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
    );
  }
}
7
likes
160
points
140
downloads
screenshot

Publisher

verified publisherthesanaullah.dev

Weekly Downloads

A highly customizable ruler/scale widget for Flutter with support for horizontal and vertical orientations, snapping, and custom styling.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on custom_ruler