StreamBuilder 강의 정리 및 설명

pharmDev·2024년 12월 9일

1. StreamBuilder 소개

StreamBuilderStream을 구독(subscribe)하여 데이터가 변화할 때마다 UI를 업데이트할 수 있도록 돕는 Flutter 위젯입니다. 비슷한 역할을 하는 FutureBuilder와는 다르게, StreamBuilder는 여러 번의 데이터 변경을 처리할 수 있는 장점이 있습니다.


2. 스트림 생성 및 StreamBuilder 적용

스트림 생성 코드

아래는 간단히 숫자를 생성하는 Stream의 예제입니다.

Stream<int> generateNumbers() async* {
  for (int i = 0; i <= 10; i++) {
    await Future.delayed(Duration(seconds: 1)); // 1초 대기
    yield i; // 숫자를 반환
  }
}
StreamBuilder로 UI 구성

StreamBuilder를 이용해 위 스트림의 데이터를 받아 UI를 업데이트할 수 있습니다.

class StreamBuilderExample extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('StreamBuilder Example')),
      body: StreamBuilder<int>(
        stream: generateNumbers(), // 스트림 연결
        builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            // 대기 상태
            return Center(child: Text('Loading...'));
          } else if (snapshot.hasError) {
            // 에러 처리
            return Center(child: Text('Error: ${snapshot.error}'));
          } else if (snapshot.connectionState == ConnectionState.active ||
              snapshot.connectionState == ConnectionState.done) {
            // 데이터가 활성 상태일 때
            return Center(
              child: Text(
                'Number: ${snapshot.data}', // 데이터 표시
                style: TextStyle(fontSize: 24),
              ),
            );
          } else {
            // 다른 경우
            return Center(child: Text('No data available'));
          }
        },
      ),
    );
  }
}

3. StreamBuilder와 FutureBuilder의 차이점

  • FutureBuilder: 단일 비동기 작업(Future)의 결과를 처리.
  • StreamBuilder: 지속적으로 들어오는 비동기 데이터 스트림(Stream)을 처리.

예시:

  • FutureBuilderwaiting -> done 순서로 상태가 변화.
  • StreamBuilderwaiting -> active -> done 순서로 상태가 변화하며, active 상태에서 데이터를 반복적으로 처리.

4. 추가 예제: 로딩 표시와 데이터 표시

데이터 로드 중에도 로딩 표시와 데이터를 함께 보여주는 UI를 구성할 수 있습니다.

class EnhancedStreamBuilder extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Enhanced StreamBuilder')),
      body: StreamBuilder<int>(
        stream: generateNumbers(),
        builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
          if (snapshot.hasData && snapshot.connectionState == ConnectionState.active) {
            // 로딩 중 데이터 표시
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                CircularProgressIndicator(), // 로딩 표시
                SizedBox(height: 20),
                Text(
                  'Number: ${snapshot.data}', // 데이터 표시
                  style: TextStyle(fontSize: 24),
                ),
              ],
            );
          } else if (snapshot.connectionState == ConnectionState.waiting) {
            // 데이터 대기 상태
            return Center(child: CircularProgressIndicator());
          } else if (snapshot.hasError) {
            // 에러 처리
            return Center(child: Text('Error: ${snapshot.error}'));
          } else if (snapshot.connectionState == ConnectionState.done) {
            // 스트림 완료
            return Center(child: Text('Stream finished!'));
          } else {
            return Center(child: Text('No data available'));
          }
        },
      ),
    );
  }
}

5. 에러 처리 예제

스트림에서 특정 조건에 따라 에러를 던질 수도 있습니다.

Stream<int> generateNumbersWithError() async* {
  for (int i = 0; i <= 10; i++) {
    if (i == 5) {
      throw Exception('An error occurred at number $i');
    }
    await Future.delayed(Duration(seconds: 1));
    yield i;
  }
}

에러가 발생했을 때의 UI 처리는 hasError 상태에서 적절히 대응합니다.

builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
  if (snapshot.hasError) {
    return Center(child: Text('Error: ${snapshot.error}'));
  }
  // 다른 상태 처리
}

6. 요약

  • StreamBuilder는 데이터의 지속적인 스트림을 처리하는 데 사용.
  • FutureBuilder와 유사하나, StreamBuilder는 여러 데이터 값을 처리할 수 있음.
  • ConnectionState에 따라 상태를 분리하여 UI 업데이트.
  • 에러, 로딩, 데이터 표시를 적절히 처리 가능.

StreamBuilder는 실시간 데이터 업데이트가 필요한 채팅 앱, 주식 데이터, IoT 센서 데이터를 처리할 때 유용합니다.

profile
코딩을 배우는 초보

0개의 댓글