플러터(Flutter) 개발에서 반응형 프로그래밍을 구현할 때, rxdart 패키지는 매우 유용한 도구입니다.
이 글에서는 rxdart 패키지를 사용하는 방법과 주요 옵션에 대해 설명합니다.
1. Rxdart 패키지란?
rxdart는 Dart 언어용 반응형 확장을 제공하는 패키지입니다.
이는 RxJava나 RxJS와 비슷한 기능을 제공하며, 스트림(Stream)과 옵저버블(Observable) 개념을 이용해 비동기 작업을 보다 쉽게 관리할 수 있게 해줍니다.
2. Rxdart 패키지 설치
우선, rxdart 패키지를 프로젝트에 추가해야 합니다. pubspec.yaml 파일에 다음을 추가하세요
dependencies:
flutter:
sdk: flutter
rxdart: ^0.27.1
그런 다음, 터미널에서 다음 명령어를 실행하여 패키지를 설치합니다
flutter pub get
3. 기본 사용법
rxdart의 기본 개념은 스트림과 옵저버블입니다. 여기서는 BehaviorSubject를 예로 들어 설명합니다.
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
// BehaviorSubject는 최신 상태를 보유하고, 새 구독자가 해당 상태를 즉시 받을 수 있게 합니다.
final BehaviorSubject<int> _counter = BehaviorSubject<int>.seeded(0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('RxDart Example'),
),
body: Center(
child: StreamBuilder<int>(
stream: _counter.stream,
builder: (context, snapshot) {
return Text('Counter: ${snapshot.data}');
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 최신 값을 얻고, 1을 더한 후 추가합니다.
_counter.add(_counter.value + 1);
},
child: Icon(Icons.add),
),
);
}
@override
void dispose() {
// 사용이 끝나면 BehaviorSubject를 닫습니다.
_counter.close();
super.dispose();
}
}
위 예제에서는 BehaviorSubject를 사용하여 카운터 상태를 관리하고, 이를 StreamBuilder를 통해 UI에 반영합니다.
4. 주요 옵션 및 연산자
rxdart는 다양한 연산자를 제공하여 스트림을 조작할 수 있습니다. 몇 가지 주요 옵션과 연산자를 살펴보겠습니다.
4.1. map
map 연산자는 스트림의 각 요소에 함수를 적용하여 새로운 스트림을 만듭니다.
final observable = Stream.fromIterable([1, 2, 3]).map((value) => value * 2);
observable.listen(print); // 2, 4, 6 출력
4.2. filter (where)
where 연산자는 스트림의 요소를 필터링하여 조건에 맞는 요소만 통과시킵니다.
final observable = Stream.fromIterable([1, 2, 3, 4, 5]).where((value) => value % 2 == 0);
observable.listen(print); // 2, 4 출력
4.3. combineLatest
combineLatest는 여러 스트림의 마지막 값을 결합하여 새로운 스트림을 만듭니다.
final observable1 = Stream.fromIterable([1, 2, 3]);
final observable2 = Stream.fromIterable([4, 5, 6]);
final combined = Rx.combineLatest2(observable1, observable2, (a, b) => a + b);
combined.listen(print); // 5, 6, 7 출력
4.4. debounce
debounce 연산자는 지정된 시간 동안 스트림의 요소 방출을 지연시킵니다.
final observable = Stream.fromIterable([1, 2, 3]).debounceTime(Duration(seconds: 1));
observable.listen(print); // 3만 출력 (debounce 때문에 앞의 요소들이 무시됨)
5. 실전 예제
rxdart를 이용하여 간단한 검색 기능을 구현해보겠습니다.
사용자가 입력하는 검색어를 받아 디바운스 처리하고, 서버에 요청을 보내 검색 결과를 표시하는 예제입니다.
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SearchPage(),
);
}
}
class SearchPage extends StatefulWidget {
@override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
final TextEditingController _controller = TextEditingController();
final BehaviorSubject<String> _searchSubject = BehaviorSubject<String>();
final List<String> _results = [];
@override
void initState() {
super.initState();
_searchSubject.stream
.debounceTime(Duration(milliseconds: 500))
.distinct()
.switchMap((query) => _search(query))
.listen((results) {
setState(() {
_results.clear();
_results.addAll(results);
});
});
}
Stream<List<String>> _search(String query) async* {
// 여기서는 간단히 검색 결과를 시뮬레이션합니다.
await Future.delayed(Duration(seconds: 1)); // 네트워크 지연 시간 시뮬레이션
yield List.generate(5, (index) => '$query 결과 $index');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('RxDart Search Example'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextField(
controller: _controller,
onChanged: (query) => _searchSubject.add(query),
decoration: InputDecoration(
hintText: '검색어를 입력하세요...',
),
),
Expanded(
child: ListView.builder(
itemCount: _results.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_results[index]),
);
},
),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
_searchSubject.close();
super.dispose();
}
}
이 예제에서는 사용자가 텍스트 필드에 입력하는 검색어를 받아 _searchSubject에 추가하고, debounceTime과 distinct 연산자를 사용하여 불필요한 네트워크 요청을 줄입니다.
그런 다음, switchMap을 사용하여 검색 결과 스트림을 처리하고 UI에 표시합니다.
마무리
rxdart 패키지를 사용하면 플러터 애플리케이션에서 반응형 프로그래밍을 쉽게 구현할 수 있습니다.
이 글에서는 rxdart의 기본 사용법과 주요 연산자에 대해 설명했습니다.
더 깊이 있는 내용을 알고 싶다면 rxdart 공식 문서와 추가 자료를 참고하세요.
'Flutter > Flutter Programming' 카테고리의 다른 글
플러터 초보를 위한 Path Provider패키지 완전 가이드: 앱 저장 공간 마스터하기 (0) | 2024.07.09 |
---|---|
플러터 초보를 위한 Sqflite 패키지 완전 가이드: 데이터베이스 마스터하기 (0) | 2024.07.09 |
플러터에서 Flutter Slidable 패키지 활용하기: 좌우 슬라이드 기능 구현 가이드 (0) | 2024.07.09 |
플러터에서 Carousel Slider 패키지 활용하기: 이미지, 텍스트, 다양한 옵션 사용법 (0) | 2024.07.09 |
플러터에서 Google Fonts 사용하기: google_fonts 패키지 사용 방법과 옵션 설명 (0) | 2024.07.09 |