seekbar 0.1.1 copy "seekbar: ^0.1.1" to clipboard
seekbar: ^0.1.1 copied to clipboard

A Flutter package with a lightweight SeekBar and an AdvancedSeekBar featuring indicators, ticks, and discrete modes.

example/lib/main.dart

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

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

class SeekBarExampleApp extends StatelessWidget {
  const SeekBarExampleApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SeekBar Example',
      theme: ThemeData.dark(),
      home: const SeekBarExamplePage(),
    );
  }
}

class SeekBarExamplePage extends StatefulWidget {
  const SeekBarExamplePage({Key? key}) : super(key: key);

  @override
  State<SeekBarExamplePage> createState() => _SeekBarExamplePageState();
}

class _SeekBarExamplePageState extends State<SeekBarExamplePage> {
  double _legacyValue = 0.35;
  double _legacySecondValue = 0.7;
  bool _legacyTracking = false;
  String _legacyEvent = 'idle';
  double _advancedContinuousValue = 34.6;
  double _advancedCallbackValue = 50;
  double _advancedCallbackChangedValue = 50;
  String _advancedCallbackState = 'idle';
  bool _advancedCallbackFromUser = false;
  int _advancedCallbackThumbIndex = 2;
  String _advancedCallbackTickText = 'Medium';
  double _advancedDiscreteValue = 50;
  bool _advancedR2l = false;
  bool _advancedOnlyThumbDraggable = false;
  bool _advancedSeekSmoothly = false;
  bool _advancedThumbAdjustAuto = true;
  bool _advancedUserSeekable = true;
  bool _advancedHideEndTicks = false;
  bool _advancedHideSweptTicks = false;
  bool _advancedBubbleIndicator = true;
  String _advancedEvent = 'idle';

  void _reset() {
    setState(() {
      _legacyValue = 0.35;
      _legacySecondValue = 0.7;
      _legacyTracking = false;
      _legacyEvent = 'reset';
      _advancedContinuousValue = 34.6;
      _advancedCallbackValue = 50;
      _advancedCallbackChangedValue = 50;
      _advancedCallbackState = 'idle';
      _advancedCallbackFromUser = false;
      _advancedCallbackThumbIndex = 2;
      _advancedCallbackTickText = 'Medium';
      _advancedDiscreteValue = 50;
      _advancedR2l = false;
      _advancedOnlyThumbDraggable = false;
      _advancedSeekSmoothly = false;
      _advancedThumbAdjustAuto = true;
      _advancedUserSeekable = true;
      _advancedHideEndTicks = false;
      _advancedHideSweptTicks = false;
      _advancedBubbleIndicator = true;
      _advancedEvent = 'reset';
    });
  }

  String _formatValue(double value) {
    return value.toStringAsFixed(2);
  }

  Widget _buildCallbackInfo(String label, String value) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 6),
      child: Text('$label: $value'),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SeekBar Example'),
      ),
      body: Center(
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 560),
          child: ListView(
            padding: const EdgeInsets.all(24),
            children: [
              _SectionCard(
                title: 'Legacy SeekBar',
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    Container(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 20,
                        vertical: 28,
                      ),
                      decoration: BoxDecoration(
                        color: Colors.black87,
                        borderRadius: BorderRadius.circular(16),
                      ),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: [
                          SeekBar(
                            value: _legacyValue,
                            secondValue: _legacySecondValue,
                            progressColor: Colors.lightBlueAccent,
                            secondProgressColor: Colors.lightBlueAccent
                                .withAlpha(89),
                            barColor: Colors.white24,
                            thumbColor: Colors.white,
                            onStartTrackingTouch: () {
                              setState(() {
                                _legacyTracking = true;
                                _legacyEvent = 'drag start';
                              });
                            },
                            onProgressChanged: (value) {
                              setState(() {
                                _legacyValue = value;
                                if (_legacySecondValue < value) {
                                  _legacySecondValue = value;
                                }
                                _legacyEvent =
                                    'drag update ${_formatValue(value)}';
                              });
                            },
                            onStopTrackingTouch: () {
                              setState(() {
                                _legacyTracking = false;
                                _legacyEvent = 'drag end';
                              });
                            },
                          ),
                          const SizedBox(height: 24),
                          Text('tracking: ${_legacyTracking ? 'yes' : 'no'}'),
                          const SizedBox(height: 8),
                          Text('last event: $_legacyEvent'),
                          const SizedBox(height: 8),
                          Text('primary value: ${_formatValue(_legacyValue)}'),
                          const SizedBox(height: 8),
                          Text(
                            'secondary value: ${_formatValue(_legacySecondValue)}',
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(height: 16),
                    const Text('Primary Value'),
                    Slider(
                      value: _legacyValue,
                      onChanged: (value) {
                        setState(() {
                          _legacyValue = value;
                          if (_legacySecondValue < value) {
                            _legacySecondValue = value;
                          }
                          _legacyEvent =
                              'primary slider ${_formatValue(value)}';
                        });
                      },
                    ),
                    const SizedBox(height: 12),
                    const Text('Secondary Value'),
                    Slider(
                      value: _legacySecondValue,
                      onChanged: (value) {
                        setState(() {
                          _legacySecondValue =
                              value < _legacyValue ? _legacyValue : value;
                          _legacyEvent =
                              'secondary slider ${_formatValue(_legacySecondValue)}';
                        });
                      },
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 20),
              _SectionCard(
                title: 'AdvancedSeekBar Continuous',
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    AdvancedSeekBar(
                      min: -20,
                      max: 120,
                      progress: _advancedContinuousValue,
                      progressValueFloat: true,
                      showThumbText: true,
                      indicatorAlwaysShown: true,
                      indicatorType: AdvancedSeekBarIndicatorType.rectangle,
                      indicatorTextFormat:
                          'value ${AdvancedSeekBarFormat.progress}',
                      activeTrackColor: Colors.orangeAccent,
                      thumbColor: Colors.orangeAccent,
                      onSeeking: (value) {
                        setState(() {
                          _advancedContinuousValue = value.progressDouble;
                          _advancedEvent =
                              'continuous ${_formatValue(value.progressDouble)}';
                        });
                      },
                    ),
                    const SizedBox(height: 12),
                    Text(
                      'continuous value: ${_formatValue(_advancedContinuousValue)}',
                    ),
                    const SizedBox(height: 12),
                    Slider(
                      min: -20,
                      max: 120,
                      value: _advancedContinuousValue,
                      onChanged: (value) {
                        setState(() {
                          _advancedContinuousValue = value;
                          _advancedEvent =
                              'continuous slider ${_formatValue(value)}';
                        });
                      },
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 20),
              _SectionCard(
                title: 'AdvancedSeekBar Callback Inspector',
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    AdvancedSeekBar(
                      min: 0,
                      max: 100,
                      progress: _advancedCallbackValue,
                      progressValueFloat: true,
                      ticksCount: 5,
                      showTickTexts: true,
                      tickTexts: const ['XS', 'S', 'Medium', 'Large', 'XL'],
                      tickMarkType: AdvancedSeekBarTickMarkType.square,
                      showThumbText: true,
                      indicatorType: AdvancedSeekBarIndicatorType.roundedRectangle,
                      indicatorTextFormat:
                          'callback ${AdvancedSeekBarFormat.progress}',
                      activeTrackColor: Colors.tealAccent,
                      thumbColor: Colors.tealAccent,
                      tickColor: Colors.tealAccent,
                      tickTextColor: Colors.white70,
                      onChanged: (value) {
                        setState(() {
                          _advancedCallbackChangedValue = value;
                        });
                      },
                      onStartTrackingTouch: () {
                        setState(() {
                          _advancedCallbackState = 'onStart';
                        });
                      },
                      onSeeking: (value) {
                        setState(() {
                          _advancedCallbackValue = value.progressDouble;
                          _advancedCallbackState = value.fromUser
                              ? 'onSeeking'
                              : 'programmatic';
                          _advancedCallbackFromUser = value.fromUser;
                          _advancedCallbackThumbIndex = value.thumbIndex;
                          _advancedCallbackTickText = value.tickText ?? '-';
                        });
                      },
                      onStopTrackingTouch: () {
                        setState(() {
                          _advancedCallbackState = 'onStop';
                          _advancedCallbackFromUser = false;
                        });
                      },
                    ),
                    const SizedBox(height: 12),
                    _buildCallbackInfo('state', _advancedCallbackState),
                    _buildCallbackInfo(
                      'progress',
                      _advancedCallbackValue.round().toString(),
                    ),
                    _buildCallbackInfo(
                      'progressDouble',
                      _formatValue(_advancedCallbackValue),
                    ),
                    _buildCallbackInfo(
                      'lastChanged',
                      _formatValue(_advancedCallbackChangedValue),
                    ),
                    _buildCallbackInfo(
                      'fromUser',
                      _advancedCallbackFromUser.toString(),
                    ),
                    _buildCallbackInfo(
                      'thumbIndex',
                      _advancedCallbackThumbIndex.toString(),
                    ),
                    _buildCallbackInfo('tickText', _advancedCallbackTickText),
                  ],
                ),
              ),
              const SizedBox(height: 20),
              _SectionCard(
                title: 'AdvancedSeekBar Discrete',
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    AdvancedSeekBar(
                      min: 0,
                      max: 100,
                      progress: _advancedDiscreteValue,
                      ticksCount: 5,
                      showTickTexts: true,
                      tickTexts: const ['XS', 'S', 'M', 'L', 'XL'],
                      tickMarkType: AdvancedSeekBarTickMarkType.oval,
                      indicatorType:
                          AdvancedSeekBarIndicatorType.roundedRectangle,
                      activeTrackColor: Colors.lightBlueAccent,
                      thumbColor: Colors.white,
                      tickTextColor: Colors.white70,
                      tickColor: Colors.lightBlueAccent,
                      r2l: _advancedR2l,
                      onlyThumbDraggable: _advancedOnlyThumbDraggable,
                      indicatorTextFormat:
                          'size ${AdvancedSeekBarFormat.tickText}',
                      onSeeking: (value) {
                        setState(() {
                          _advancedDiscreteValue = value.progressDouble;
                          _advancedEvent =
                              'discrete idx=${value.thumbIndex} text=${value.tickText}';
                        });
                      },
                    ),
                    const SizedBox(height: 12),
                    Text('advanced event: $_advancedEvent'),
                    const SizedBox(height: 8),
                    SwitchListTile(
                      contentPadding: EdgeInsets.zero,
                      title: const Text('RTL'),
                      value: _advancedR2l,
                      onChanged: (value) {
                        setState(() {
                          _advancedR2l = value;
                        });
                      },
                    ),
                    SwitchListTile(
                      contentPadding: EdgeInsets.zero,
                      title: const Text('Only Thumb Draggable'),
                      value: _advancedOnlyThumbDraggable,
                      onChanged: (value) {
                        setState(() {
                          _advancedOnlyThumbDraggable = value;
                        });
                      },
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 20),
              _SectionCard(
                title: 'AdvancedSeekBar Hidden Params',
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    AdvancedSeekBar(
                      min: 0,
                      max: 100,
                      progress: _advancedDiscreteValue,
                      ticksCount: 6,
                      showTickTexts: true,
                      tickTexts: const [
                        '0',
                        '20',
                        '40',
                        '60',
                        '80',
                        '100',
                      ],
                      tickMarkType: AdvancedSeekBarTickMarkType.divider,
                      showThumbText: true,
                      userSeekable: _advancedUserSeekable,
                      seekSmoothly: _advancedSeekSmoothly,
                      thumbAdjustAuto: _advancedThumbAdjustAuto,
                      tickMarksEndsHide: _advancedHideEndTicks,
                      tickMarksSweptHide: _advancedHideSweptTicks,
                      indicatorType: _advancedBubbleIndicator
                          ? AdvancedSeekBarIndicatorType.bubble
                          : AdvancedSeekBarIndicatorType.none,
                      activeTrackColor: Colors.purpleAccent,
                      thumbColor: Colors.purpleAccent,
                      tickColor: Colors.purpleAccent,
                      tickTextColor: Colors.white70,
                      indicatorTextFormat:
                          'value ${AdvancedSeekBarFormat.progress}',
                      onSeeking: (value) {
                        setState(() {
                          _advancedDiscreteValue = value.progressDouble;
                          _advancedEvent =
                              'hidden params ${_formatValue(value.progressDouble)}';
                        });
                      },
                    ),
                    const SizedBox(height: 12),
                    Text('hidden params event: $_advancedEvent'),
                    const SizedBox(height: 8),
                    SwitchListTile(
                      contentPadding: EdgeInsets.zero,
                      title: const Text('Seek Smoothly'),
                      value: _advancedSeekSmoothly,
                      onChanged: (value) {
                        setState(() {
                          _advancedSeekSmoothly = value;
                        });
                      },
                    ),
                    SwitchListTile(
                      contentPadding: EdgeInsets.zero,
                      title: const Text('Thumb Adjust Auto'),
                      value: _advancedThumbAdjustAuto,
                      onChanged: (value) {
                        setState(() {
                          _advancedThumbAdjustAuto = value;
                        });
                      },
                    ),
                    SwitchListTile(
                      contentPadding: EdgeInsets.zero,
                      title: const Text('User Seekable'),
                      value: _advancedUserSeekable,
                      onChanged: (value) {
                        setState(() {
                          _advancedUserSeekable = value;
                        });
                      },
                    ),
                    SwitchListTile(
                      contentPadding: EdgeInsets.zero,
                      title: const Text('Hide End Ticks'),
                      value: _advancedHideEndTicks,
                      onChanged: (value) {
                        setState(() {
                          _advancedHideEndTicks = value;
                        });
                      },
                    ),
                    SwitchListTile(
                      contentPadding: EdgeInsets.zero,
                      title: const Text('Hide Swept Ticks'),
                      value: _advancedHideSweptTicks,
                      onChanged: (value) {
                        setState(() {
                          _advancedHideSweptTicks = value;
                        });
                      },
                    ),
                    SwitchListTile(
                      contentPadding: EdgeInsets.zero,
                      title: const Text('Bubble Indicator'),
                      value: _advancedBubbleIndicator,
                      onChanged: (value) {
                        setState(() {
                          _advancedBubbleIndicator = value;
                        });
                      },
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 16),
              Align(
                alignment: Alignment.centerRight,
                child: ElevatedButton(
                  onPressed: _reset,
                  child: const Text('Reset'),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _SectionCard extends StatelessWidget {
  const _SectionCard({required this.title, required this.child});

  final String title;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(title, style: Theme.of(context).textTheme.titleMedium),
            const SizedBox(height: 16),
            child,
          ],
        ),
      ),
    );
  }
}
7
likes
150
points
134
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter package with a lightweight SeekBar and an AdvancedSeekBar featuring indicators, ticks, and discrete modes.

Repository (GitHub)
View/report issues

Topics

#seekbar #slider #progress #media #widget

License

MIT (license)

Dependencies

flutter

More

Packages that depend on seekbar