[Flutter] Custom Switch

길위에 히피·2023년 5월 8일
0

Flutter

목록 보기
10/40

flutter 에서 토글 스위치가 기본으로 제공 되지만 모양을 커스텀 하는것이 제한된다.
다른 라이브러리들은 토글이 트랙커 안에 위치하는 모양이어서,
내가 생각하는 토글보다 작은 트랙커 사이즈를 만드는게 제한된다.
그래서 직접 만들었다.

import 'package:flutter/material.dart';

class CustomSwitch extends StatefulWidget {
  final Function(bool value) onChanged;
  final bool value;
  final double trackWidth;
  final double trackHeight;
  final double toggleWidth;
  final double toggleHeight;
  final Color toggleActiveColor;
  final Color trackInActiveColor;
  final Color trackActiveColor;
  const CustomSwitch({
    required this.onChanged,
    required this.value,
    this.trackHeight =5,
    this.trackWidth = 20,
    this.toggleWidth =10,
    this.toggleHeight =10,
    this.trackActiveColor =const Color(0xffcccccc),
    this.trackInActiveColor =const Color(0xffcccccc),
    this.toggleActiveColor =const Color(0xff6385e6),

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

class _CustomSwitchState extends State<CustomSwitch> {
  bool _isSwitched = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _isSwitched = !_isSwitched;
        });
      },
      child: Container(
        width: widget.trackWidth,
        height: widget.toggleHeight>widget.trackHeight?widget.toggleHeight:widget.trackHeight,
        child: Stack(
          alignment: Alignment.center,
          children: [
            Container(
              width: widget.trackWidth,
              height: widget.trackHeight,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(15.0),
                color: _isSwitched ? widget.trackActiveColor : widget.trackInActiveColor,
              ),),
            AnimatedPositioned(
              duration: Duration(milliseconds: 200),
              curve: Curves.ease,
              left: _isSwitched ? 10.0 : 0.0,
              child: GestureDetector(
                onHorizontalDragUpdate: (DragUpdateDetails details) {
                  setState(() {
                    double newPosition = details.localPosition.dx;
                    if (newPosition < -15.0) {
                      newPosition = -15.0;
                    } else if (newPosition > 15.0) {
                      newPosition = 15.0;
                    }
                    _isSwitched = newPosition > 0.0;
                  });
                },
                child: Container(
                  width:widget.toggleWidth,
                  height:widget.toggleHeight,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    color: widget.toggleActiveColor,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

사용법은 일반 스위치와 동일하다.

  CustomSwitch(
            value: isSwitched,
            onChanged: (value) {
              setState(() {
                isSwitched = value;
              });
            },
          )

추가적인 변수를 통해서 트랙과 토글의 크기와 색깔이 변경이 가능하다.

trackWidth, trackHeight: 스위치 트랙의 크기.
toggleWidth, toggleHeight: 스위치 토글의 크기.
toggleActiveColor: 스위치가 활성화되었을 때 토글의 색상.
trackInActiveColor, trackActiveColor: 각각 비활성 및 활성 상태일 때 스위치 트랙의 색상.

https://github.com/ironfactory8684/custom_switch

profile
마음맘은 히피인 일꾼러

0개의 댓글