GestureDetector를 이용한 대기 버튼 만들기

2024-02-23 17:42 | Flutter

GestureDetector 위젯의 OnLongPress를 이용한 원형 프로그래스바 만들기

버튼을 누른 상태를 유지하는 동안 progress 값이 0.02씩 증가하고 1.1에 도달하면 자동으로 cancelTimer 호출

  • onLongPressStart : 버튼을 누른상태를 유지하면 상태 진행률이 진행됨 0.0 -> 1.0

  • OnLongPressEnd : 버튼에서 떼면 cancelTimer를 실행시키고 진행률 0.0으로 전환

진행률 표기를 위한 타이머 실행/취소 작성

  double _progressValue = 0.0;
  late Timer circularMt;
  String _textLabel = "Stop";
 
  startProgress(){
    const dur = const Duration(milliseconds: 100);
    circularMt = Timer.periodic(dur, (mt) {
      setState(() {
        _progressValue += 0.02;
        _textLabel = "Loading";
        if(_progressValue.toStringAsFixed(1) == '1.1'){
          setState(() {
            _progressValue = 0.0;
            _textLabel = "Stop";
            mt.cancel();
          });
        }
      });
    });
  }
 
  cancelTimer(){
    setState(() {
      _textLabel = "Stop";
      _progressValue = 0.0;
      circularMt.cancel();
    });
  }
 

onLongPressStart, onLongPressEnd 이벤트 수신

  • Stack 위젯을 이용하여 두 개의 CircularProgressIndicator 위젯을 겹침
  • Stack 상단에는 원형 진행률 백그라운드, 하단에는 원형 progress bar의 진행 상태 표기
@override
Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            GestureDetector(
              onTap: () {
                print("onTap()");
              },
              onLongPressStart: (_) {
                startProgress();
              },
              onLongPressEnd: (_) {
                print("onLongPressEnd $_progressValue");
 
                if(_progressValue > 0){
 
                }else{
                }
                cancelTimer();
              },
              child: Stack(
                alignment: Alignment.center,
                children: <Widget>[
                  const SizedBox(
                      width: 200,
                      height: 200,
                      child: CircularProgressIndicator(
                        strokeWidth: 10,
                        value: 1.0,
                        valueColor: AlwaysStoppedAnimation<Color>(Colors.grey),
                      )
                  ),
                  SizedBox(
                      width: 200,
                      height: 200,
                      child: CircularProgressIndicator(
                        strokeWidth: 24,
                        value: _progressValue,
                        valueColor: const AlwaysStoppedAnimation<Color>(Colors.blue),
                      )
                  ),
                  Text("${_textLabel}",
                    style: TextStyle(fontSize: 20, color:Colors.black),)
                ],
              ),
            ),
          ],
        ),
      ),
    );
}