반응형

RefreshIndicator

RefreshIndicator는 Flutter에서 사용자가 목록을 끌어 당겨서 새로 고침(pull-to-refresh) 동작을 수행할 수 있게 하는 위젯입니다. 주로 스크롤 가능한 목록에서 사용되며, 사용자에게 데이터를 새로 고치는 기능을 제공합니다.

주요 속성

  • child: RefreshIndicator가 감싸는 스크롤 가능한 위젯입니다. 일반적으로 ListView와 같은 위젯이 사용됩니다.
  • onRefresh: 새로 고침 동작이 발생할 때 호출되는 콜백 함수입니다. 이 함수는 Future<void>를 반환하여 비동기 작업을 수행할 수 있습니다.
  • color: 인디케이터의 색상을 지정합니다.
  • backgroundColor: 인디케이터의 배경색을 지정합니다.
  • displacement: 인디케이터가 표시될 때 위쪽에서 떨어진 거리입니다.
  • strokeWidth: 인디케이터의 선 두께입니다.

사용 예제

아래는 RefreshIndicator를 사용하여 목록을 새로 고침하는 예제입니다.

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('RefreshIndicator Example'),
        ),
        body: RefreshIndicatorExample(),
      ),
    );
  }
}

class RefreshIndicatorExample extends StatefulWidget {
  @override
  _RefreshIndicatorExampleState createState() => _RefreshIndicatorExampleState();
}

class _RefreshIndicatorExampleState extends State<RefreshIndicatorExample> {
  final List<String> _items = List.generate(20, (index) => 'Item ${index + 1}');

  Future<void> _refresh() async {
    await Future.delayed(Duration(seconds: 2)); // 2초 동안 대기

    setState(() {
      _items.shuffle(); // 아이템을 섞어서 목록을 새로 고침
    });
  }

  @override
  Widget build(BuildContext context) {
    return RefreshIndicator(
      onRefresh: _refresh,
      child: ListView.builder(
        itemCount: _items.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(_items[index]),
          );
        },
      ),
    );
  }
}

 

주요 포인트

  1. RefreshIndicator 사용:
    • RefreshIndicator 위젯은 스크롤 가능한 위젯을 감싸서 사용합니다.
    • onRefresh 콜백은 데이터를 새로 고침하는 로직을 포함해야 하며, Future<void>를 반환해야 합니다.
  2. 데이터 새로 고침:
    • onRefresh 콜백 내에서 비동기 작업을 수행하여 데이터를 새로 고칩니다.
    • 비동기 작업이 완료되면 setState를 호출하여 UI를 업데이트합니다.
  3. UI 업데이트:
    • setState를 사용하여 데이터 변경 사항을 반영하고 UI를 업데이트합니다.

추가 예제: 커스텀 인디케이터

기본적인 사용 예제 외에도 RefreshIndicator의 속성을 사용하여 커스텀 인디케이터를 만들 수 있습니다.

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('Custom RefreshIndicator Example'),
        ),
        body: CustomRefreshIndicatorExample(),
      ),
    );
  }
}

class CustomRefreshIndicatorExample extends StatefulWidget {
  @override
  _CustomRefreshIndicatorExampleState createState() => _CustomRefreshIndicatorExampleState();
}

class _CustomRefreshIndicatorExampleState extends State<CustomRefreshIndicatorExample> {
  final List<String> _items = List.generate(20, (index) => 'Item ${index + 1}');

  Future<void> _refresh() async {
    await Future.delayed(Duration(seconds: 2));

    setState(() {
      _items.shuffle();
    });
  }

  @override
  Widget build(BuildContext context) {
    return RefreshIndicator(
      onRefresh: _refresh,
      color: Colors.white,
      backgroundColor: Colors.blue,
      displacement: 40,
      strokeWidth: 3,
      child: ListView.builder(
        itemCount: _items.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(_items[index]),
          );
        },
      ),
    );
  }
}

 

dio 를 이용한 데이터 가져오기 예시 (실습)

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';

import 'product.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final Dio dio = Dio();

  Future<List<Product>> getProductData() async {
    try {
      print("데이터 가져오기 시작");
      var response = await dio.get("https://dummyjson.com/products");
      List<Product> products = (response.data['products'] as List)
          .map<Product>((json) => Product.fromJson(json))
          .toList();
      print("데이터 가져오기 완료");
      return products;
    } catch (e) {
      print("오류 발생: $e");
      return []; // 에러 발생 시 빈 리스트 반환
    }
  }

  Future<void> refreshData() async {
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("제품 목록"),
      ),
      body: RefreshIndicator(
        onRefresh: refreshData,
        child: FutureBuilder<List<Product>>(
          future: getProductData(),
          builder: (BuildContext context, AsyncSnapshot<List<Product>> snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Center(child: CircularProgressIndicator());
            } else if (snapshot.hasError) {
              return Center(child: Text('오류 발생: ${snapshot.error}'));
            } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
              return const Center(child: Text('데이터가 없습니다'));
            } else {
              return ListView.builder(
                itemCount: snapshot.data!.length,
                itemBuilder: (BuildContext context, int index) {
                  var data = snapshot.data![index];
                  return Container(
                    padding: const EdgeInsets.all(10),
                    decoration: BoxDecoration(
                      border: Border.all(width: 1, color: Colors.black12),
                    ),
                    child: Text("${data.title} (${data.description})"),
                  );
                },
              );
            }
          },
        ),
      ),
    );
  }
}

결론

RefreshIndicator는 Flutter에서 사용자가 목록을 끌어 당겨서 새로 고침 동작을 수행할 수 있게 하는 유용한 위젯입니다. 이 위젯을 사용하면 사용자 경험을 향상시키고, 데이터 업데이트를 쉽게 처리할 수 있습니다. RefreshIndicator를 사용하여 간단한 pull-to-refresh 기능을 구현하고, 다양한 속성을 통해 커스터마이징할 수 있습니다.

참고 문서

반응형

'프론트엔드 > Flutter' 카테고리의 다른 글

flutter provider 패턴  (1) 2024.07.22
flutter bloc 패턴 적용  (0) 2024.07.22
dart 반복문 정리  (0) 2024.07.21
dart 조건문 정리  (0) 2024.07.21
dart collection 설명 및 예시  (0) 2024.07.21

+ Recent posts