본문 바로가기
Flutter

Flutter의 NotificationListener로 위젯 간 소통하기: 상태 변화 감지 및 반응형 UI 만들기

by 김무스비 2024. 10. 30.
728x90
반응형

Flutter에서 UI는 계층적 트리 구조로 구성되기 때문에 위젯 간에 상태를 공유하거나 특정 이벤트를 부모 위젯에 알리는 작업이 필요할 때가 있습니다. Flutter의 NotificationListener 위젯은 이러한 작업을 간편하게 수행할 수 있도록 돕는 도구입니다. 자식 위젯에서 발생한 특정 이벤트를 부모 위젯이 수신하고 이에 반응할 수 있는 구조를 만들 수 있으며, 주로 스크롤 이벤트나 애니메이션 변화 같은 상태를 감지할 때 유용하게 사용됩니다.

이번 포스트에서는 NotificationListener 위젯의 기본 사용법과 활용 가능한 다양한 예제를 통해 어떻게 이벤트를 감지하고 상태 변화를 반영하는지 자세히 알아보겠습니다.

notification image


1. NotificationListener란?

NotificationListener는 자식 위젯에서 발생하는 알림(또는 이벤트)을 감지하고 처리할 수 있는 Flutter 위젯입니다. 특정 알림 유형을 수신하여 이벤트를 처리할 수 있는 구조를 제공하며, 이를 통해 위젯 트리 내의 다른 위젯들과 효율적으로 상호작용할 수 있습니다.

주요 특징:

  • 스크롤 이벤트 감지: 스크롤 위치나 스크롤 상태 변화 이벤트를 감지할 수 있습니다.
  • 알림 전파 제어: 특정 조건에 맞는 알림만 수신하도록 필터링이 가능합니다.
  • UI 업데이트: 이벤트에 반응하여 UI를 동적으로 업데이트하거나 특정 작업을 수행할 수 있습니다.

2. NotificationListener의 주요 구성 요소

NotificationListener는 크게 다음 두 가지 요소로 구성됩니다:

  • onNotification: 자식 위젯에서 발생한 알림을 수신하고 처리하는 콜백 함수입니다. 이 함수는 Notification을 파라미터로 받아, 발생한 이벤트의 종류와 상태를 확인한 후 적절한 반응을 설정할 수 있습니다.
  • Notification: 이벤트나 알림을 나타내는 객체로, 여러 유형이 있습니다. 일반적으로 사용되는 Notification에는 ScrollNotification, SizeChangedLayoutNotification 등이 있습니다.

3. NotificationListener 기본 사용법

NotificationListener는 특정 조건을 충족하는 이벤트를 감지하여, 부모 위젯이 이를 받아 처리할 수 있게 하는 데 사용됩니다. 기본 예제를 통해 스크롤 이벤트를 감지하고, 스크롤 위치에 따라 상태를 업데이트하는 방법을 알아보겠습니다.

예제: 스크롤 위치 감지하기

import 'package:flutter/material.dart';

class ScrollNotificationExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("NotificationListener 예제")),
      body: NotificationListener<ScrollNotification>(
        onNotification: (ScrollNotification notification) {
          // 스크롤 위치를 확인하고 스크롤 상태에 반응합니다.
          if (notification is ScrollStartNotification) {
            print("스크롤 시작");
          } else if (notification is ScrollUpdateNotification) {
            print("스크롤 위치 업데이트: ${notification.metrics.pixels}");
          } else if (notification is ScrollEndNotification) {
            print("스크롤 종료");
          }
          return true;
        },
        child: ListView.builder(
          itemCount: 30,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text("아이템 $index"),
            );
          },
        ),
      ),
    );
  }
}

이 예제에서는 NotificationListener가 스크롤 시작, 업데이트, 종료 이벤트를 감지하여 콘솔에 출력하는 방식으로 동작합니다. ScrollNotification은 ScrollStartNotification, ScrollUpdateNotification, ScrollEndNotification 등의 서브 클래스들을 통해 다양한 스크롤 이벤트를 전달하며, 이를 통해 각 상태에 맞는 이벤트 처리가 가능합니다.

4. 다양한 NotificationListener 활용 예제

1) 스크롤 위치에 따라 AppBar 색상 변경하기

스크롤 위치에 따라 상단 AppBar의 색상을 변경하는 방법입니다. 사용자가 스크롤할 때 UI의 배경색을 동적으로 변경하는 기능을 통해 좀 더 직관적이고 반응형인 사용자 경험을 제공할 수 있습니다.

import 'package:flutter/material.dart';

class ScrollColorChangeExample extends StatefulWidget {
  @override
  _ScrollColorChangeExampleState createState() => _ScrollColorChangeExampleState();
}

class _ScrollColorChangeExampleState extends State<ScrollColorChangeExample> {
  Color _appBarColor = Colors.blue;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: _appBarColor,
        title: Text("스크롤에 따른 AppBar 색상 변경"),
      ),
      body: NotificationListener<ScrollNotification>(
        onNotification: (ScrollNotification notification) {
          if (notification is ScrollUpdateNotification) {
            setState(() {
              // 스크롤 위치에 따라 색상을 다르게 설정
              _appBarColor = notification.metrics.pixels > 100 ? Colors.red : Colors.blue;
            });
          }
          return true;
        },
        child: ListView.builder(
          itemCount: 20,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text("아이템 $index"),
            );
          },
        ),
      ),
    );
  }
}

위 예제에서는 스크롤이 100픽셀 이상일 때 AppBar의 색상을 빨간색으로 변경하고, 그렇지 않으면 파란색으로 설정합니다. ScrollUpdateNotification을 통해 스크롤 위치를 실시간으로 확인하여 동적으로 색상을 변경할 수 있습니다.

2) 스크롤 깊이에 따라 아이템 크기 조절하기

스크롤 위치에 따라 리스트 아이템의 크기를 다르게 설정하는 예제입니다. 스크롤 깊이에 따라 아이템을 점점 축소하여 표시할 수 있습니다.

import 'package:flutter/material.dart';

class ScrollSizeAdjustmentExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("스크롤에 따른 아이템 크기 조절"),
      ),
      body: NotificationListener<ScrollNotification>(
        onNotification: (ScrollNotification notification) {
          return true;
        },
        child: ListView.builder(
          itemCount: 20,
          itemBuilder: (context, index) {
            return LayoutBuilder(
              builder: (context, constraints) {
                return Container(
                  height: 100 - index * 2.0, // 스크롤할수록 크기가 작아짐
                  color: Colors.teal[(index % 9) * 100],
                  alignment: Alignment.center,
                  child: Text("아이템 $index", style: TextStyle(fontSize: 18)),
                );
              },
            );
          },
        ),
      ),
    );
  }
}

5. NotificationListener 사용 시 주의 사항

NotificationListener 사용 시 몇 가지 주의할 사항이 있습니다:

  • 이벤트 처리 범위 제한: NotificationListener는 여러 이벤트를 동시에 처리할 수 있어 잘못 사용할 경우 불필요한 리소스가 낭비될 수 있습니다. 따라서 불필요한 이벤트는 무시하거나 특정 조건에서만 반응하도록 설정하는 것이 좋습니다.
  • 퍼포먼스 관리: 알림이 너무 자주 발생하면, 예를 들어 매우 빠른 스크롤 상태에서 이벤트가 계속 호출되면 성능이 저하될 수 있습니다. 필요한 경우 debounce나 throttle 기법을 사용하여 이벤트 호출 빈도를 제한하는 것도 방법입니다.
  • onNotification에서 true 반환: onNotification 콜백 함수 내에서 true를 반환하면 이벤트가 더 이상 전파되지 않고, false를 반환하면 이벤트가 계속 전파됩니다.

결론

Flutter의 NotificationListener 위젯은 자식 위젯의 상태 변화를 부모 위젯에 전달하고 UI를 반응형으로 만드는 데 유용한 도구입니다. 특히 스크롤 위치에 따라 상태를 감지하고 UI를 동적으로 업데이트하는 다양한 기능을 제공합니다. 이벤트를 효율적으로 관리하고 상태에 맞게 반응형 UI를 구현하는 데 있어 NotificationListener의 사용법과 특징을 이해하면 더욱 강력한 Flutter 애플리케이션을 구축할 수 있습니다.

728x90
반응형