Flutter

Flutter 이벤트 사용법

devfinger 2025. 2. 2. 17:33

onPressed, onTap과 같은 콜백 함수 방식

ElevatedButton(
  onPressed: () {
    print("버튼이 클릭됨");
  },
  child: Text("클릭"),
)

 

GestureDetector 터치 이벤트 감지

GestureDetector(
  onTap: () {
    print("화면이 터치됨");
  },
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

 

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("GestureDetector Example")),
        body: Center(
          child: GestureDetector(
            onTap: () {
              print("onTap: 화면을 터치했습니다.");
            },
            onDoubleTap: () {
              print("onDoubleTap: 화면을 두 번 터치했습니다.");
            },
            onLongPress: () {
              print("onLongPress: 화면을 오래 눌렀습니다.");
            },
            onPanUpdate: (details) {
              print("onPanUpdate: 손가락 이동 중 - ${details.delta}");
            },
            child: Container(
              width: 200,
              height: 200,
              color: Colors.blue,
              alignment: Alignment.center,
              child: Text(
                "Touch Me",
                style: TextStyle(color: Colors.white, fontSize: 20),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
  • onTap: 짧게 터치하면 발생
  • onDoubleTap: 빠르게 두 번 터치하면 발생
  • onLongPress: 길게 누르면 발생
  • onPanUpdate: 손가락이 이동할 때마다 발생

 

 

Listener 이벤트 감지

Listener(
  onPointerDown: (event) => print("손가락이 눌림"),
  onPointerMove: (event) => print("손가락이 움직임"),
  onPointerUp: (event) => print("손가락이 뗌"),
  child: Container(
    width: 100,
    height: 100,
    color: Colors.red,
  ),
)

 

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("Listener Example")),
        body: Center(
          child: Listener(
            onPointerDown: (event) => print("onPointerDown: 터치 시작"),
            onPointerMove: (event) => print("onPointerMove: 손가락 이동 중"),
            onPointerUp: (event) => print("onPointerUp: 터치 종료"),
            child: Container(
              width: 200,
              height: 200,
              color: Colors.red,
              alignment: Alignment.center,
              child: Text(
                "Touch Me",
                style: TextStyle(color: Colors.white, fontSize: 20),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

 

 

  • onPointerDown: 터치를 시작할 때 발생
  • onPointerMove: 손가락이 이동할 때 발생
  • onPointerUp: 터치를 끝낼 때 발생

 

 

InkWell 터치 이벤트 감지

InkWell(
  onTap: () {
    print("InkWell 터치됨");
  },
  child: Container(
    width: 100,
    height: 100,
    color: Colors.green,
  ),
)

 

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("InkWell Example")),
        body: Center(
          child: InkWell(
            onTap: () {
              print("onTap: 버튼 터치됨");
            },
            onLongPress: () {
              print("onLongPress: 버튼 길게 누름");
            },
            borderRadius: BorderRadius.circular(10),
            child: Container(
              width: 200,
              height: 50,
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: Colors.green,
                borderRadius: BorderRadius.circular(10),
              ),
              child: Text(
                "Press Me",
                style: TextStyle(color: Colors.white, fontSize: 20),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

 

 

  • onTap: 짧게 터치하면 발생
  • onLongPress: 길게 누르면 발생
  • InkWell은 버튼을 감싸고 터치하면 잉크 효과를 줌

 

onTap, onDoubleTap, onLongPress, onPanUpdate 이벤트 발생 순서

 

이벤트동작 방식

onTap 짧게 터치하면 발생
onDoubleTap 빠르게 두 번 터치하면 발생
onLongPress 길게 누르고 있으면 발생 (이후 손을 떼도 onTap 발생 안 함)
onPanUpdate 손가락이 움직일 때마다 발생

 

onLongPress가 발생하면 onTap은 발생하지 않음.

 

 

 

 

위젯 이벤트

위젯                     이벤트 속성
ElevatedButton          onPressed, onLongPress
TextButton              onPressed, onLongPress
OutlinedButton          onPressed, onLongPress
IconButton              onPressed, onLongPress
FloatingActionButton    onPressed
GestureDetector         onTap, onDoubleTap, onLongPress, onPanUpdate
InkWell                 onTap, onDoubleTap, onLongPress
ListView                onScrollNotification (스크롤 이벤트 감지)
TextField               onChanged, onSubmitted, onEditingComplete, onTap
Switch                  onChanged
Checkbox                onChanged
Slider                  onChanged, onChangeEnd

 

이벤트 처리시 REST API 통신 예제

1) 버튼 클릭시 REST API 호출

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("REST API 예제")),
        body: Center(
          child: ElevatedButton(
            onPressed: fetchData,
            child: Text("API 호출"),
          ),
        ),
      ),
    );
  }

  void fetchData() async {
    var url = Uri.parse("https://jsonplaceholder.typicode.com/todos/1");
    var response = await http.get(url);
    if (response.statusCode == 200) {
      var data = jsonDecode(response.body);
      print("데이터: $data");
    } else {
      print("API 요청 실패");
    }
  }
}

 

 

2) TextField 입력 시 REST API 호출

TextField(
  onChanged: (text) async {
    var url = Uri.parse("https://api.example.com/search?q=$text");
    var response = await http.get(url);
    if (response.statusCode == 200) {
      print("검색 결과: ${response.body}");
    }
  },
  decoration: InputDecoration(
    hintText: "검색어 입력",
  ),
)

 

3) ListView 스크롤 시 API 호출

NotificationListener<ScrollNotification>(
  onNotification: (scrollNotification) {
    if (scrollNotification.metrics.pixels == scrollNotification.metrics.maxScrollExtent) {
      print("리스트 끝에 도달. 추가 데이터 로드");
      fetchMoreData();
    }
    return true;
  },
  child: ListView.builder(
    itemCount: 20,
    itemBuilder: (context, index) {
      return ListTile(title: Text("아이템 $index"));
    },
  ),
)

 

ListView 아이템 추가 및 터치 이벤트 처리 예제

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ListViewExample(),
    );
  }
}

class ListViewExample extends StatefulWidget {
  @override
  _ListViewExampleState createState() => _ListViewExampleState();
}

class _ListViewExampleState extends State<ListViewExample> {
  List<String> items = ["Item 1", "Item 2", "Item 3"];

  void _addItem() {
    setState(() {
      items.add("Item ${items.length + 1}");
    });
  }

  void _removeItem(int index) {
    setState(() {
      items.removeAt(index);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("ListView Example")),
      body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(items[index]),
            onTap: () {
              print("${items[index]} 클릭됨");
            },
            onLongPress: () {
              _removeItem(index);
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _addItem,
        child: Icon(Icons.add),
      ),
    );
  }
}

 

  • ListView.builder: 동적으로 리스트 생성
  • onTap: 리스트 아이템 터치 시 이벤트 발생
  • onLongPress: 아이템을 길게 누르면 삭제됨
  • FloatingActionButton: 새 아이템 추가

'Flutter' 카테고리의 다른 글

Flutter 업데이트 (마켓, Shorebird)  (0) 2025.02.02
Flutter 기본 정리  (0) 2025.02.02