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.

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
  • It was a little difficult to me. Do you know the idea behind onChanged?
    – mohammad
    Commented Dec 29, 2019 at 19:36
  • 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.
    – J. S.
    Commented Dec 29, 2019 at 20:24

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.