0

I try to build my own slider in flutter.

but I face a problem.

how to create a callback like flutter default slider onChanged ???? in order to have our own slider we need to register a callBack but I don't have any idea how ?

this is my effort until now.

import 'dart:math';

import 'package:flutter/material.dart';

class WaveSlider extends StatefulWidget {
  final double value;
  final double barWidth;
  final int maxBarHight;
  final double width;
  final double min;
  final double max;
  final Color barColor;
  final Color barSideColor;
  final Color inActiveColor;

  WaveSlider({
    this.value = 0.0,
    this.barWidth = 5.0,
    this.maxBarHight = 50,
    this.width = 60.0,
    this.min = 0.0,
    this.max = 1.0,
    this.barColor = Colors.white,
    this.barSideColor = Colors.black,
    this.inActiveColor = Colors.grey,
  });
  @override
  State<StatefulWidget> createState() => WaveSliderState();
}

class WaveSliderState extends State<WaveSlider>
    with SingleTickerProviderStateMixin {
  AnimationController positionController;

  List<int> bars = [];
  double barPosition;
  double barWidth;
  int maxBarHight;
  double width;

  int numberOfBars;

  @override
  void initState() {
    super.initState();
    barPosition = widget.value;
    barWidth = widget.barWidth;
    maxBarHight = widget.maxBarHight.toInt();
    width = widget.width;
    if (bars.isNotEmpty) bars = [];
    numberOfBars = width ~/ barWidth;
    randomNumberGenerator();
  }

  void randomNumberGenerator() {
    Random r = Random();
    for (var i = 0; i < numberOfBars; i++) {
      bars.add(r.nextInt(maxBarHight - 10) + 10);
    }
  }

  _onTapDown(TapDownDetails details) {
    var x = details.globalPosition.dx;
    print("tapped " + (x).toString());
    // print(positionController.value);
    setState(() {
      barPosition = x;
    });
  }

  void _onHorizontalDragUpdate(DragUpdateDetails details) {
    setState(() {
      barPosition = details.globalPosition.dx;
    });
  }

  @override
  Widget build(BuildContext context) {
    int barItem = 0;
    return Center(
      child: GestureDetector(
        onTapDown: _onTapDown,
        onHorizontalDragUpdate: _onHorizontalDragUpdate,
        child: Container(
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.end,
            mainAxisAlignment: MainAxisAlignment.center,
            children: bars.map((int height) {
              Color color = barItem + 1 < barPosition / barWidth
                  ? widget.barColor
                  : widget.inActiveColor;
              barItem++;
              return Row(
                children: <Widget>[
                  Container(
                    width: .1,
                    height: height.toDouble(),
                    color: widget.barSideColor,
                  ),
                  Container(
                    decoration: BoxDecoration(
                      color: color,
                      borderRadius: BorderRadius.only(
                        topLeft: const Radius.circular(1.0),
                        topRight: const Radius.circular(1.0),
                      ),
                    ),
                    height: height.toDouble(),
                    width: 4.8,
                  ),
                  Container(
                    width: .1,
                    height: height.toDouble(),
                    color: widget.barSideColor,
                  ),
                ],
              );
            }).toList(),
          ),
        ),
      ),
    );
  }
}

you can use it like:

WaveSlider(
          value: _animation.value,
          min: 0.0,
          max: 1.0,
          width: MediaQuery.of(context).size.width,
          barWidth: 5,
          maxBarHight: 50,
          barColor: Colors.black,
          barSideColor: Colors.white,
          inActiveColor: Colors.red,
        )

I look at default flutter slider but it was very complected for me . Thanks alot .

2 Answers 2

2

I have added callback as below:

import 'dart:math';

import 'package:flutter/material.dart';

class WaveSlider extends StatefulWidget {
  final double value;
  final double barWidth;
  final int maxBarHight;
  final double width;
  final double min;
  final double max;
  final Color barColor;
  final Color barSideColor;
  final Color inActiveColor;
  final CalbackFunction callback;

  WaveSlider({
    this.value = 0.0,
    this.barWidth = 5.0,
    this.maxBarHight = 50,
    this.width = 60.0,
    this.min = 0.0,
    this.max = 1.0,
    this.barColor = Colors.white,
    this.barSideColor = Colors.black,
    this.inActiveColor = Colors.grey,
    this.callback,
  });
  @override
  State<StatefulWidget> createState() => WaveSliderState();
}

class WaveSliderState extends State<WaveSlider>
    with SingleTickerProviderStateMixin {
  AnimationController positionController;

  List<int> bars = [];
  double barPosition;
  double barWidth;
  int maxBarHight;
  double width;

  int numberOfBars;

  @override
  void initState() {
    super.initState();
    barPosition = widget.value;
    barWidth = widget.barWidth;
    maxBarHight = widget.maxBarHight.toInt();
    width = widget.width;
    if (bars.isNotEmpty) bars = [];
    numberOfBars = width ~/ barWidth;
    randomNumberGenerator();
  }

  void randomNumberGenerator() {
    Random r = Random();
    for (var i = 0; i < numberOfBars; i++) {
      bars.add(r.nextInt(maxBarHight - 10) + 10);
    }
  }

  _onTapDown(TapDownDetails details) {
    var x = details.globalPosition.dx;
    // print("tapped " + (x).toString());
    widget.callback(details.globalPosition); /// <-- I used callback here
    // print(positionController.value);
    setState(() {
      barPosition = x;
    });
  }

  void _onHorizontalDragUpdate(DragUpdateDetails details) {
    widget.callback(details.globalPosition); /// <-- I used callback here
    setState(() {
      barPosition = details.globalPosition.dx;
    });
  }

  @override
  Widget build(BuildContext context) {
    int barItem = 0;
    return Center(
      child: GestureDetector(
        onTapDown: _onTapDown,
        onHorizontalDragUpdate: _onHorizontalDragUpdate,
        child: Container(
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.end,
            mainAxisAlignment: MainAxisAlignment.center,
            children: bars.map((int height) {
              Color color = barItem + 1 < barPosition / barWidth
                  ? widget.barColor
                  : widget.inActiveColor;
              barItem++;
              return Row(
                children: <Widget>[
                  Container(
                    width: .1,
                    height: height.toDouble(),
                    color: widget.barSideColor,
                  ),
                  Container(
                    decoration: BoxDecoration(
                      color: color,
                      borderRadius: BorderRadius.only(
                        topLeft: const Radius.circular(1.0),
                        topRight: const Radius.circular(1.0),
                      ),
                    ),
                    height: height.toDouble(),
                    width: 4.8,
                  ),
                  Container(
                    width: .1,
                    height: height.toDouble(),
                    color: widget.barSideColor,
                  ),
                ],
              );
            }).toList(),
          ),
        ),
      ),
    );
  }
}

typedef CalbackFunction = void Function(Offset value);

you can use it as below:

WaveSlider(
            value: 0.0,
            min: 0.0,
            max: 1.0,
            width: MediaQuery.of(context).size.width,
            barWidth: 5,
            maxBarHight: 50,
            barColor: Colors.black,
            barSideColor: Colors.white,
            inActiveColor: Colors.red,
            callback: (offset) {
              print("callback " + (offset.dx).toString());
            },
          ))

I hope it can help you.

Sign up to request clarification or add additional context in comments.

Comments

0

The documentation of the wave_slider package shows that it has an onChanged property for a callback:

WaveSlider(
  onChanged: (double dragUpdate) {
    setState(() {
    _dragPercentage = dragUpdate *
        100; // dragUpdate is a fractional value between 0 and 1
    });
  },
)

2 Comments

It was a little difficult to me. Do you know the idea behind onChanged?
It gets called whenever the user moves the slider and it gives you the value between 0 and 100 at which the slider is in.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.