본문 바로가기
Flutter

[Flutter] 밀어서 잠금해제 슬라이더(unlock slider) 구현하기

by 김무스비 2024. 11. 14.
728x90
반응형

오늘은 밀어서 잠금해제 후 다른 화면으로 navigate하는 unlock slider를 구현해보겠슴니다


1. 우선, 슬라이더를 미는 과정이 화면에 보여야 하므로 StatefulWidget를 만들어줍니다.


class UnlockSlider extends StatefulWidget {
  const UnlockSlider({super.key});

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

 

2. 그 다음, state를 관리하는 class에서 슬라이더의 현재 위치, 전체 너비, 버튼 너비를 할당해줄 변수를 선언합니다.

class _UnlockSliderState extends State<UnlockSlider> {
  double _dragPosition = 0.0;
  final double _sliderWidth = 300.0; // 슬라이더 전체 너비 설정
  final double _sliderButtonWidth = 50.0; // 슬라이더 버튼 너비 설정
 
// 아래 생략 //
 
}

 

3. 드래그 이벤트 핸들러 만들기

1)DragUpdateDetails 클래스의 details.primaryDelta는 드래그된 거리의 변화량인데, 이걸 현재 _dragPosition에 더해서 슬라이더 버튼의 위치를 업데이트한다.

2)단, _dragPosition이 왼쪽 끝을 넘어가면 0으로 설정해준다(=맨 앞으로 가져온다, 왼쪽끝에서 더 안 움직이게 한다).

3)단, 슬라이더 너비에서 버튼 너비를 뺀 값보다 크면, 즉 오른쪽 경계를 넘어서면 _dragPosition을 최대 위치로 설정한다. (여기서 최대 위치는 슬라이더 버튼이 안에 완전히 들어갈 수 있는 최대 위치다. _sliderWidth - _sliderButtonWidth )


  void _onHorizontalDragUpdate(DragUpdateDetails details) {
    setState(() {
      _dragPosition += details.primaryDelta!;
      // 드래그 위치를 슬라이더 너비 내로 제한
      if (_dragPosition < 0) {
        _dragPosition = 0;
      } else if (_dragPosition > _sliderWidth - _sliderButtonWidth) {
        _dragPosition = _sliderWidth - _sliderButtonWidth;
      }
    });
  }

 

4. 드래그 종료 핸들러 만들기

1)슬라이더가 끝에 도달하면(= _dragPosition >= _sliderWidth - _sliderButtonWidth 이면)다음 화면으로 이동(여기서는 PageOne)함과 동시에 슬라이더를 맨앞으로 다시 보내줍니다.(이거 안하면 슬라이더 있는 페이지로 돌아왔을때 슬라이더가 맨 끝에 가있음)

2)임계값에 도달하지 못하면 맨 처음 위치로 되돌림


  void _onHorizontalDragEnd(DragEndDetails details) {
    if (_dragPosition >= _sliderWidth - _sliderButtonWidth) {
      // 슬라이더가 끝에 도달하면 다음 화면으로 이동
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => const PageOne()),
      ).then((_) {
        // 뒤로 돌아왔을 때 슬라이더 위치 초기화
        setState(() {
          _dragPosition = 0.0;
        });
      });
    } else {
      // 임계값에 도달하지 못하면 슬라이더를 원래 위치로 되돌림
      setState(() {
        _dragPosition = 0.0;
      });
    }
  }

이상입니다. 

읽어주셔서 감사합니다.

728x90
반응형