30

In my application, I want the switch is used to toggle a setting between on/off which is true/false respectively. When I went to build it, it turned out that Flutter provides a default switch, but it is not what I want. I want to customize it accordingly to my UI.

This is the Flutter switch button:

Enter image description here

Here is what I want:

Enter image description here

How can I make it possible for my UI?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sumit Tifane
  • 379
  • 1
  • 3
  • 7

5 Answers5

48

Set

bool _switchValue = true;

in your screen.dart file:

 CupertinoSwitch(
              value: _switchValue,
              onChanged: (value) {
                setState(() {
                  _switchValue = value;
                });
              },
            ),
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • Please explain why and how your solution works. Maybe add a reference or link a documentation and please properly format your posts. However, im not sure your answer solves OP question. He asked about the design, not value-switching. – bam Mar 12 '20 at 13:19
  • they want design like switchbutton on ios and CupertinoSwitch solve what they want and i set "bool _switchValue=true;" to just know is the var the contain the state of switchbutton – makri aymen abderraouf Mar 12 '20 at 22:09
  • How do you make the circluar button to be bigger thatn the strip? – Sisir Nov 19 '21 at 17:21
  • use Switch widget, CupertinoSwitch is using the switch of ios devices , but if you wanna the normal switch use the switch of Matrial design – makri aymen abderraouf Nov 22 '21 at 18:37
24

You can use package https://pub.dev/packages/custom_switch or fork it and modify it to your needs.

Full code

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.deepOrange
      ),
      home: HomeScreen(),
    );
  }
}


class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  bool status = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Switch Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            CustomSwitch(
              activeColor: Colors.pinkAccent,
              value: status,
              onChanged: (value) {
                print("VALUE : $value");
                setState(() {
                  status = value;
                });
              },
            ),
            SizedBox(height: 12.0,),
            Text('Value : $status', style: TextStyle(
              color: Colors.black,
              fontSize: 20.0
            ),)
          ],
        ),
      ),
    );
  }
}

Enter image description here

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
chunhunghan
  • 51,087
  • 5
  • 102
  • 120
24

Create a custom switch class

class CustomSwitch extends StatefulWidget {
  final bool value;
  final ValueChanged<bool> onChanged;

  CustomSwitch({Key? key, required this.value, required this.onChanged})
      : super(key: key);

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

class _CustomSwitchState extends State<CustomSwitch>
    with SingleTickerProviderStateMixin {
  Animation? _circleAnimation;
  AnimationController? _animationController;

  @override
  void initState() {
    super.initState();
    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 60));
    _circleAnimation = AlignmentTween(
            begin: widget.value ? Alignment.centerRight : Alignment.centerLeft,
            end: widget.value ? Alignment.centerLeft : Alignment.centerRight)
        .animate(CurvedAnimation(
            parent: _animationController!, curve: Curves.linear));
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animationController!,
      builder: (context, child) {
        return GestureDetector(
          onTap: () {
            if (_animationController!.isCompleted) {
              _animationController!.reverse();
            } else {
              _animationController!.forward();
            }
            widget.value == false
                ? widget.onChanged(true)
                : widget.onChanged(false);
          },
          child: Container(
            width: 45.0,
            height: 28.0,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(24.0),
              color: _circleAnimation!.value == Alignment.centerLeft
                  ? Colors.grey
                  : Colors.blue,
            ),
            child: Padding(
              padding: const EdgeInsets.only(
                  top: 2.0, bottom: 2.0, right: 2.0, left: 2.0),
              child: Container(
                alignment:
                    widget.value ? ((Directionality.of(context) == TextDirection.rtl) ? Alignment.centerRight : Alignment.centerLeft ) : ((Directionality.of(context) == TextDirection.rtl) ? Alignment.centerLeft : Alignment.centerRight),
                child: Container(
                  width: 20.0,
                  height: 20.0,
                  decoration: BoxDecoration(
                      shape: BoxShape.circle, color: Colors.white),
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}

Call this class as widget and use the value parameter to set the state of the switch

bool _enable = false;

CustomSwitch(
   value: _enable,
   onChanged: (bool val){
      setState(() {
         _enable = val;
      });
   },
),
AnasSafi
  • 5,353
  • 1
  • 35
  • 38
Nitesh Kumar Verma
  • 405
  • 1
  • 4
  • 8
10

For a custom switch, I used this package: https://pub.dev/packages/flutter_switch

You can customize the height and width of the switch, the border radius of the switch, the colors, the toggle size, etc.

Install:

dependencies:
     flutter_switch: ^0.0.2

Import:

import 'package:flutter_switch/flutter_switch.dart';

Sample Usage:

FlutterSwitch(
     height: 20.0,
     width: 40.0,
     padding: 4.0,
     toggleSize: 15.0,
     borderRadius: 10.0,
     activeColor: lets_cyan,
     value: isToggled,
     onToggle: (value) {
          setState(() {
                isToggled = value;
          });
     },
),

Flutter Switch

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nickr
  • 216
  • 4
  • 8
  • Hi, [Links to external resources are encouraged, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline.](https://stackoverflow.com/help/how-to-answer) – manuel_b May 09 '20 at 16:07
  • Nick, it is good that you (and other) contributes some helpful stuffs, But you should carefully test it.Widget won't updates when I change the value by setState. Look at CupertinoSwitch for example. Thanks – A.Y. Jul 30 '20 at 15:07
3

You can achieve such a design using this package:

This usage is from their README file:

import 'package:custom_switch_button/custom_switch_button.dart';

bool isChecked = false;

return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Custom Switch Button example app'),
        ),
        body: GestureDetector(
          onTap: () {
            setState(() {
              isChecked = !isChecked;
            });
          },
          child: Center(
            child: CustomSwitchButton(
              backgroundColor: Colors.blueGrey,
              unCheckedColor: Colors.white,
              animationDuration: Duration(milliseconds: 400),
              checkedColor: Colors.lightGreen,
              checked: isChecked,
            ),
          ),
        ),
      ),
    );

Final result:

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Taha Malas
  • 200
  • 2
  • 12