반응형

Flutter에서 서로 떨어진 위젯 간에 데이터를 주고받는 방법은 여러 가지가 있습니다. 상황에 맞는 방법을 선택하면 됩니다.


1. InheritedWidget / InheritedModel

  • 특징: 하위 위젯에서 변경 사항을 감지하고 UI를 다시 빌드할 수 있음.
  • 사용 예시: 앱 전반에서 공유해야 하는 설정, 테마 등.
class MyInheritedWidget extends InheritedWidget {
  final int counter;

  const MyInheritedWidget({
    Key? key,
    required this.counter,
    required Widget child,
  }) : super(key: key, child: child);

  static MyInheritedWidget? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
  }

  @override
  bool updateShouldNotify(MyInheritedWidget oldWidget) {
    return oldWidget.counter != counter;
  }
}

2. Provider (Riverpod, flutter_bloc 등 포함)

  • 특징: 상태 관리 라이브러리를 사용하여 위젯 간 상태를 공유.
  • 사용 예시: 전역 상태 관리가 필요한 경우.
final counterProvider = StateProvider<int>((ref) => 0);

class CounterWidget extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);
    return Text('$count');
  }
}


3. Navigator를 통한 데이터 전달 (push & pop)

  • 특징: 새로운 화면을 열 때 데이터를 전달하거나, 닫을 때 데이터를 반환.
  • 사용 예시: 새로운 화면에서 데이터를 입력받아 이전 화면으로 전달할 때.
// 데이터 전달하며 이동
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => SecondScreen(data: 'Hello')),
);

// SecondScreen에서 데이터 반환
Navigator.pop(context, 'Returned Data');

4. Event Bus (StreamController)

  • 특징: 특정 이벤트를 발생시키면 여러 위젯에서 이를 감지하고 반응.
  • 사용 예시: 독립적인 위젯들이 동일한 이벤트를 수신해야 할 때.
final eventBus = StreamController<String>.broadcast();

// 이벤트 발생
eventBus.add("새로운 데이터");

// 이벤트 수신
eventBus.stream.listen((event) {
  print("이벤트 수신: $event");
});

5. GlobalKey 사용

  • 특징: 특정 위젯의 상태를 전역적으로 접근 가능하게 만듦.
  • 사용 예시: 다른 위젯에서 특정 위젯의 메서드를 직접 호출해야 할 때.
final GlobalKey<ScaffoldMessengerState> scaffoldKey = GlobalKey<ScaffoldMessengerState>();

scaffoldKey.currentState?.showSnackBar(SnackBar(content: Text('알림')));

6. MethodChannel (Flutter ↔ Native)

  • 특징: 네이티브 코드(Android, iOS)와 통신할 때 사용.
  • 사용 예시: 네이티브 기능(카메라, GPS 등)과 데이터 주고받기.
static const platform = MethodChannel('com.example.method_channel');

Future<void> sendData() async {
  final result = await platform.invokeMethod('getBatteryLevel');
}

📌 결론

  • 간단한 상태 공유 → InheritedWidget, Provider
  • 전역 상태 관리 → Provider, Riverpod, BLoC
  • 화면 간 데이터 전달 → Navigator
  • 이벤트 기반 통신 → EventBus(StreamController)
  • 특정 위젯 조작 → GlobalKey

사용하는 패턴과 앱 구조에 따라 적절한 방법을 선택하면 됩니다. 🚀

반응형

+ Recent posts