Flutter Gesture 완벽 가이드: 제스처란 무엇이고 어떻게 활용할까?
Flutter에서 Gesture(제스처) 는 사용자의 터치 이벤트를 감지하고 UI와 상호작용하는 데 필수적인 요소입니다. 이번 블로그에서는 Gesture란 무엇인지, 종류, 메서드와 옵션들 에 대해 자세히 알아보겠습니다.
1. Gesture(제스처)란?
Gesture는 사용자의 터치 이벤트(탭, 스와이프, 드래그 등) 를 감지하여 UI 요소와 상호작용할 수 있도록 합니다. Flutter는 GestureDetector 위젯을 통해 제스처를 감지할 수 있으며, 이를 활용하여 다양한 인터랙션을 구현할 수 있습니다.
예를 들어, 버튼을 탭했을 때 특정 동작을 수행하거나, 스와이프하여 페이지를 넘기는 기능을 만들 수 있습니다.
💡 GestureDetector의 기본 사용 예제
GestureDetector(
onTap: () {
print("화면이 탭되었습니다!");
},
child: Container(
width: 100,
height: 100,
color: Colors.blue,
child: Center(child: Text("탭!")),
),
)
이 코드를 실행하면, 해당 컨테이너를 탭할 때 콘솔에 화면이 탭되었습니다! 가 출력됩니다.
2. Gesture의 종류
Flutter에서 지원하는 주요 제스처는 다음과 같습니다:
제스처 설명
onTap | 화면을 터치 후 떼었을 때 발생하는 이벤트 (일반적인 클릭) |
onDoubleTap | 빠르게 두 번 터치했을 때 발생하는 이벤트 |
onLongPress | 길게 눌렀을 때 발생하는 이벤트 |
onVerticalDragStart | 위/아래로 드래그 시작 시 발생하는 이벤트 |
onVerticalDragUpdate | 위/아래로 드래그하는 동안 지속적으로 발생하는 이벤트 |
onVerticalDragEnd | 위/아래로 드래그 종료 시 발생하는 이벤트 |
onHorizontalDragStart | 좌/우로 드래그 시작 시 발생하는 이벤트 |
onHorizontalDragUpdate | 좌/우로 드래그하는 동안 지속적으로 발생하는 이벤트 |
onHorizontalDragEnd | 좌/우로 드래그 종료 시 발생하는 이벤트 |
onPanStart | 터치를 시작할 때 발생하는 이벤트 |
onPanUpdate | 터치를 이동하는 동안 지속적으로 발생하는 이벤트 |
onPanEnd | 터치를 끝냈을 때 발생하는 이벤트 |
3. GestureDetector의 주요 옵션
3.1 onTap, onDoubleTap, onLongPress (기본적인 터치 이벤트)
GestureDetector(
onTap: () => print("탭 이벤트 발생!"),
onDoubleTap: () => print("더블탭 이벤트 발생!"),
onLongPress: () => print("롱 프레스 이벤트 발생!"),
child: Container(
width: 150,
height: 150,
color: Colors.orange,
child: Center(child: Text("탭 or 롱프레스")),
),
)
3.2 드래그 이벤트 (onPan, onVerticalDrag, onHorizontalDrag)
GestureDetector(
onPanUpdate: (details) {
print("사용자가 이동 중: ${details.delta}");
},
child: Container(
width: 200,
height: 200,
color: Colors.green,
child: Center(child: Text("드래그 해보세요!")),
),
)
💡 onPanUpdate 를 사용하면 손가락이 움직이는 방향과 거리를 details.delta 로 받을 수 있습니다.
3.3 제스처 중첩 해결 (behavior 속성 활용)
Flutter의 GestureDetector는 기본적으로 자식 위젯이 이벤트를 가로챌 경우 이벤트가 감지되지 않는 문제가 발생할 수 있습니다. 이를 해결하기 위해 behavior: HitTestBehavior.opaque 옵션을 추가할 수 있습니다.
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => print("탭 이벤트 발생!"),
child: Container(
width: 150,
height: 150,
color: Colors.purple,
child: Center(child: Text("탭 가능!")),
),
)
4. Gesture를 지원하는 다른 위젯들
Flutter에는 GestureDetector 외에도 기본적으로 제스처를 지원하는 위젯들이 있습니다.
1) Slider (드래그 기반의 값 변경)
Slider(
value: _sliderValue,
min: 0,
max: 100,
onChanged: (newValue) {
setState(() => _sliderValue = newValue);
},
)
💡 Slider는 사용자가 드래그하여 값을 변경할 수 있도록 도와줍니다.
2) PopupMenuButton (롱프레스 또는 탭으로 팝업 메뉴 표시)
PopupMenuButton<String>(
onSelected: (String result) {
print("선택한 메뉴: $result");
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
PopupMenuItem<String>(value: "옵션 1", child: Text("옵션 1")),
PopupMenuItem<String>(value: "옵션 2", child: Text("옵션 2")),
],
)
💡 PopupMenuButton을 사용하면 특정 요소를 롱프레스하거나 탭할 때 메뉴를 표시할 수 있습니다.
<Flutter Setting>
01. What is pubspec?
pubspec.yaml 파일은 Flutter 프로젝트의 설정을 정의하는 파일입니다. 주요 항목은 다음과 같습니다.
name: my_app
version: 1.0.0+1
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
- dependencies: 외부 패키지 목록
- dev_dependencies: 테스트 및 개발용 패키지 목록
- flutter: 프로젝트의 기본 설정
02. Flutter에서 외부 라이브러리를 쓰기
Flutter는 pub.dev에서 다양한 외부 라이브러리를 가져와 사용할 수 있습니다.
1) 패키지 추가
flutter pub add http
2) 코드에서 사용
import 'package:http/http.dart' as http;
void fetchData() async {
var response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
print(response.body);
}
03. Flutter에서 로컬 데이터를 활용하기
Flutter에서 로컬 데이터를 저장하는 방법으로 SharedPreferences와 sqflite가 있습니다.
1) SharedPreferences 사용 (간단한 데이터 저장)
import 'package:shared_preferences/shared_preferences.dart';
void saveData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('username', 'flutter_dev');
}
void loadData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? username = prefs.getString('username');
print("Loaded Username: $username");
}
2) sqflite 사용 (SQLite 데이터베이스 활용)
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
Future<Database> initializeDB() async {
String path = join(await getDatabasesPath(), 'my_database.db');
return openDatabase(
path,
onCreate: (db, version) {
return db.execute(
"CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)"
);
},
version: 1,
);
}
'App > flutter' 카테고리의 다른 글
플러터 상태관리(statelessWidget, statefulWidget) (1) | 2023.12.05 |
---|---|
상태관리 : bloc 과 provider에 대해서 (2) | 2023.11.29 |