GestureDetector를 사용하던 중 onTapUp과 onTapDown만 사용하던 중 불편한 점을 발견. 불편한 점이 무엇이냐면 보통의 상황에서는 눌렀다 떼면 원하는 기능이 잘 작동한다. 그러나 TapDown상태에서 손가락을 끌어서 나중에 놓는 경우 onTapUp이 작동하지 않음.
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
bool isClickedBtn1 = false;
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test',
home: Scaffold(
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
GestureDetector(
onTapUp: (_) => setState(() {
isClickedBtn1 = false;
}),
onTapDown: (_) => setState(() {
isClickedBtn1 = true;
}),
child: Container(
width: 100,
height: 100,
color: Colors.amberAccent,
child: Center(
child: isClickedBtn1
? const Text('Clicked')
: const Text('button1'),
),
),
),
],
),
),
),
);
}
}
위 코드는 onTapUp과 onTapDown만 사용한 코드.
이를 해결하기 위해서 onTapCancel을 사용.
onTapCancel: () => setState(() {
isClickedBtn1 = false;
}),
그러나, onTapCancel을 사용했는데 또 불편한 점이 발생.
버튼을 누른 상태(TapDown)에서 손가락을 누른 상태로 끌어서 움직이면 onTapUp 대신 onTapCancel이 호출되는데, 이때 약간만 움직여도 onTapCancel이 호출 되어 맘에 들지 않음.
그래서 Listener를 사용하는 방법 채택.
Listener(
onPointerDown: (details) {
setState(() {
isClickedBtn2 = true;
});
},
onPointerUp: (details) {
setState(() {
isClickedBtn2 = false;
});
},
child: Container(
width: 100,
height: 100,
color: Colors.amberAccent,
child: Center(
child: isClickedBtn2 ? const Text('Clicked') : const Text('button2'),
),
),
),
내가 딱 원하던 동작을 수행함. TapDown 상태에서 손가락을 끌어서 TapUp을 하면 onTapUp이 호출되는 동작을 생각한다면 Listener를 사용하는 게 나을 거 같다.
전체 코드
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
bool isClickedBtn1 = false;
bool isClickedBtn2 = false;
class _MyAppState extends State<MyApp> {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
GestureDetector(
onTapUp: (_) => setState(() {
isClickedBtn1 = false;
}),
onTapDown: (_) => setState(() {
isClickedBtn1 = true;
}),
onTapCancel: () => setState(() {
isClickedBtn1 = false;
}),
child: Container(
width: 100,
height: 100,
color: Colors.amberAccent,
child: Center(
child: isClickedBtn1
? const Text('Clicked')
: const Text('button1'),
),
),
),
Listener(
onPointerDown: (details) {
setState(() {
isClickedBtn2 = true;
});
},
onPointerUp: (details) {
setState(() {
isClickedBtn2 = false;
});
},
child: Container(
width: 100,
height: 100,
color: Colors.amberAccent,
child: Center(
child: isClickedBtn2
? const Text('Clicked')
: const Text('button2'),
),
),
),
],
),
),
),
);
}
}
'Flutter' 카테고리의 다른 글
Flutter; ElevatedButton으로 클릭 효과 구현 (MaterialStateProperty) (0) | 2024.03.29 |
---|---|
Flutter; Container로 커스텀 애니메이션 (눌림 효과) 버튼 구현하기 (2) | 2024.03.29 |
댓글