We are going to create Custom Switch in Flutter . We will start by creating a fresh new Flutter Project . To create a new Flutter project run

flutter create projectName

After that we will have a folder named projectName , inside that in lib/ create a new file named customSwitch.dart . Inside that we will create a StatefulWidget named  CustomSwitch and Create a constructor for the required fields like

class CustomSwitch extends StatefulWidget {
  final bool value;
  final ValueChanged<bool> onChanged;
  final Color activeColor;
  final Color inactiveColor;
  final Color baseColor;

  const CustomSwitch({
    Key key,
    this.value,
    this.onChanged,
    this.activeColor = Colors.green,
    this.baseColor = Colors.grey,
    this.inactiveColor = Colors.red,
  }) : super(key: key);

  @override
  _CustomSwitchState createState() => _CustomSwitchState();
}

class _CustomSwitchState extends State<CustomSwitch>
    with SingleTickerProviderStateMixin {

  @override
  Widget build(BuildContext context) {
	return Container();
  }
}


We will then create AnimationController , an Animation of type Double and  a variable of double type to store animation's current value  in _CustomSwitchState

  Animation<double> _animation;
  AnimationController _animationController;
  double value;

We will then override the initState to initialize our variables as follows

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
        vsync: this,
        duration: Duration(milliseconds: 80),
        value: widget.value ? 1.0 : 0.0);
    _animation =
        CurvedAnimation(parent: _animationController, curve: Curves.easeInOut);
    value = widget.value ? 1.0 : 0.0;
    _animationController.addListener(() {
      setState(() {
        value = _animation.value;
      });
    });
  }

In the above code i have manually set the animation duration to 80ms , and the curve that animation would follow to EaseInOut , You can find more curve options here . Also i am initializing value based on initial value provided to us through constructor .

And then we will move to our build function , i will have a widget structure similar to

- GestureDetector(To respond to tap events)
  - Stack (To have multiple children on top of eachOther)
    - Container (LowerMost layer showing the base color)
    - Transform.Translate (To move the underlying widgets on x axis)
    	- Opacity (To control visibility)
    		- Container (To show the Color )
    - Transform.Translate (To move the underlying widgets on x axis	
    	- Opacity (To control visibility)
    		- Container (To show the Color ) 

The code of build would be as follows :

@override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        if (_animationController.isCompleted) {
          _animationController.reverse();
        } else {
          _animationController.forward();
        }
        widget.value == false
            ? widget.onChanged(true)
            : widget.onChanged(false);
      },
      child: Stack(
        children: [
          Container(
            width: 70.0,
            height: 35.0,
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(5.0),
                color: widget.baseColor),
          ),
          Transform.translate(
            offset: Offset(35 * value, 0), //original
            child: Opacity(
              opacity: (1 - value).clamp(0.0, 1.0),
              child: Container(
                  height: 30.0,
                  width: 30,
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(5.0),
                      color: widget.inactiveColor),
                  margin: const EdgeInsets.all(2.5)),
            ),
          ),
          Transform.translate(
            offset: Offset(35 * value, 0), //original
            child: Opacity(
              opacity: value.clamp(0.0, 1.0),
              child: Container(
                height: 30.0,
                width: 30,
                margin: const EdgeInsets.all(2.5),
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(5.0),
                    color: widget.activeColor),
              ),
            ),
          ),
        ],
      ),
    );
  }


Then at the end we will dispose the _animationController .

Hope You Have learnt How to create Custom Switch in Flutter , But if you want to Just use it . I have already provided this code as a package . Source Code here .

Reach out on my Social Handles if you have any problems with this