Flutter

[Flutter] GestureDetector 위젯

미로910 2024. 11. 14. 09:50

GestureDetector 위젯

 

  • GestureDetector는 사용자가 화면에서 수행하는 다양한 터치 이벤트를 감지하고 처리하는 기본적인 Flutter 위젯입니다.
  • GestureDetector 자체는 화면에 표시되지 않으며, child에 지정된 위젯에 사용자 이벤트가 발생할 때 이벤트를 처리할 수 있습니다.
  • 이 위젯은 다양한 사용자 이벤트에 대한 콜백 함수들로 구성되어 있어, 각 이벤트에 맞는 동작을 정의할 수 있습니다.

주요 GestureDetector 콜백 함수

  • onTap: 사용자가 화면을 가볍게 탭할 때 호출됩니다. (예: 버튼 클릭 효과)
  • onDoubleTap: 사용자가 화면을 빠르게 두 번 탭할 때 호출됩니다. (예: 이미지 확대)
  • onLongPress: 사용자가 화면을 오래 누르고 있을 때 호출됩니다. (예: 아이템 삭제 옵션 표시)
  • onTapDown: 사용자가 화면을 터치하기 시작할 때 호출됩니다. (예: 버튼을 누르는 즉시 효과 적용)
  • onTapUp: 사용자가 터치한 손가락을 화면에서 떼었을 때 호출됩니다. (예: 클릭 완료)
  • onVerticalDragStart: 사용자가 화면을 위아래로 드래그하기 시작할 때 호출됩니다. (예: 목록 스크롤 시작 감지)
  • onHorizontalDragStart: 사용자가 화면을 좌우로 드래그하기 시작할 때 호출됩니다. (예: 슬라이드 메뉴 호출)

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('드래그 기능 만들어 보기'),
        ),
        body: DraggableBox(),
      ),
    );
  }
}

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

  @override
  State<DraggableBox> createState() => _DraggableBoxState();
}

class _DraggableBoxState extends State<DraggableBox> {
  
  double _xOffset = 2.0; // x 축 이동 값
  double _yOffset = 5.0; // y 축 이동 값
  
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      // 드래그가 없데이트 될 때 호출 되는 콜백 함수
      onPanUpdate: (details) {

        setState(() {

          _xOffset += details.delta.dx; // x 축 방향으로 이동한 값
          _yOffset += details.delta.dy; // y 축 방향으로 이동한 값

        });
        },


      child: Stack(
        children: [
          Positioned(
            left: _xOffset,
            top: _yOffset,
            child: Container(
              width: 150,
              height: 150,
              decoration: BoxDecoration(
                color: Colors.blue,
                border: Border.all(width: 1.0, color: Colors.redAccent),
                borderRadius: BorderRadius.circular(8.0)
              ),
            ),
          )
        ],
      ),
    );
  }
}