반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

welcome to my blog

[Flutter] SmartRefresher 정리 본문

Flutter

[Flutter] SmartRefresher 정리

_annie_ 2022. 2. 16. 20:19
728x90

리스트뷰를 하단으로 스크롤하면서 데이터를 그때그때 받아 올 때 사용할 만한 라이브러리

 

사용 라이브러리

pull_to_refresh: ^2.0.0
dio: ^4.0.4

 

사용 플러그인

FlutterJsonBeanFactory 4.3.2

 

임시로 데이터가 필요하기때문에 instantwebtools.net의 fake rest api 를 이용하여 테스트 해보겠다.

https://instantwebtools.net/fake-rest-api

 

Fake Rest API | Instant Web Tools

When Data Getting Reset? As of now, we are going to open this API to the world through the public internet. So people could use this API whenever they need wherever they need. So data will be junked and deleted by the time, So we are running the data reset

instantwebtools.net

 

FAKE API -> Available Endpoints 

 

사용한 url : 

https://api.instantwebtools.net/v1/passenger?page=0&size=10

 

url을 입력하면 해당 결과값을 json 형태로 보여줌

https://jsonformatter.curiousconcept.com/#

 

JSON Formatter & Validator

Format and validate JSON data so that it can easily be read by human beings.

jsonformatter.curiousconcept.com

 

 

 

본격 시작

 

데이터 가져오기

다음 url을 https://jsonformatter.curiousconcept.com/# 의 JSON Data/URL에 넣고 결과값을 받는다.

https://api.instantwebtools.net/v1/passenger?page=0&size=10

url 을 작성한다

 

결과값

결과값이 아래 나온다.

null-able 체크

 

생성할 클래스 이름을 작성해주고 아래에는 결과값으로 반환된 값을 넣어준다.

 

passenger_model_entity.dart 파일(model)과 generated 폴더 등 자동으로 생성됨

 

stateful widget을 하나 만든다 (예제에서는 TestHomePage)

 

변수 정의 

/// 현재 페이지 정보
int currentPage = 1;

/// 전체 페이지 정보
late int totalPages;

/// 수신 데이터 리스트
List<PassengerModelData>? passengers = [];

/// Refresher controller 생성
/// initialRefresh : SmartRefresher가 초기화되면 즉시 requestRefresh를 호출합니다.
final RefreshController refreshController =
      RefreshController(initialRefresh: true);

scaffold의 body에 SmartRefresher 추가

 

SmartRefresher 추가

SmartRefresher의 controller에 refreshController 연결. child에는 ListView 추가

 

onRefresh, onLoading 에 다음코드 추가

onRefresh : 콜백이 발생하면 [RefreshController]를 사용하여 새로 고침 상태를 종료해야 합니다. 그렇지 않으면 새로 고침 상태를 유지합니다.

onLoading : 콜백이 발생하면 [RefreshController]를 사용하여 로드 상태를 종료해야 합니다. 그렇지 않으면 로드 상태를 유지합니다.

onRefresh: () async {
          final result = await getPassengerData(isRefresh: true);
          if (result) {
            refreshController.refreshCompleted();
          } else {
            refreshController.refreshFailed();
          }
        },
        onLoading: () async {
          final result = await getPassengerData();
          if (result) {
            refreshController.loadComplete();
          } else {
            refreshController.loadFailed();
          }
        },

 

getPassengerData 함수 정의

Future<bool> getPassengerData({bool isRefresh = false}) async {
    if (isRefresh) {
    /// 리스트뷰 상단에서 아래쪽으로 내리는 동작을 하면 refresh true
    /// currentpage를 1로 해서 목록을 초기화 시킴
      currentPage = 1;
    } else {
    /// 전체 페이지보다 현재 페이지가 크면 => 마지막 페이지면 더이상 로드 할 게 없음
      if (currentPage >= totalPages) {
        refreshController.loadNoData();
        return false;
      }
    }

	/// size 에 넣은 값 만큼 개수를 가져온다.
    String url =
        "https://api.instantwebtools.net/v1/passenger?page=$currentPage&size=20";
        
    /// Dio 라이브러리를 이용하여 url 의 응답을 받아온다.     
    final response = await Dio().get(url);
    
    /// 정상 응답일 경우
    if (response.statusCode == 200) {
      PassengerModelEntity tempIteaam = PassengerModelEntity();
  
  	/// result에 파싱한 데이터를 넣는다.
      final result = $PassengerModelEntityFromJson(response.data);
    
	/// 새로고침 인 경우 passengers 리스트변수를 해당 값으로 초기화
      if (isRefresh) {
        passengers = result.data;
      } else {
      
      /// 새로고침이 아닌경우(최 하단에서 올리는 동작인 경우) passengers변수에 데이터 이어붙임
        passengers!.addAll(result.data!);
      }
      
      /// 현재 페이지 +1
      currentPage++;
      
      totalPages = result.totalPages!;
      
      /// 수신된 데이터 확인
      print(response.data);
      
      /// 변수 업데이트
      setState(() {});

      return true;
    } else {
      return false;
    }
  }

 

수신된 response 데이터를 이용하여 ListView UI에 자유롭게 표현해주면 됨

 

[전체 코드]

/// test_future.dart

import 'package:abcworks/generated/json/passenger_model_entity.g.dart';
import 'package:abcworks/screens/main/my/passenger_model_entity.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

Future<void> main() async {
  runApp(MaterialApp(
    title: "test title",
    home: TestHomePage(),
  ));
}

class TestHomePage extends StatefulWidget {
  const TestHomePage({Key? key}) : super(key: key);

  @override
  _TestHomePageState createState() => _TestHomePageState();
}

class _TestHomePageState extends State<TestHomePage> {
  int currentPage = 1;
  late int totalPages;

  List<PassengerModelData>? passengers = [];

  final RefreshController refreshController =
      RefreshController(initialRefresh: true);

  Future<bool> getPassengerData({bool isRefresh = false}) async {
    if (isRefresh) {
      currentPage = 1;
    } else {
      if (currentPage >= totalPages) {
        refreshController.loadNoData();
        return false;
      }
    }

    String url =
        "https://api.instantwebtools.net/v1/passenger?page=$currentPage&size=20";
    final response = await Dio().get(url);
    if (response.statusCode == 200) {
      PassengerModelEntity tempIteaam = PassengerModelEntity();
   
      final result = $PassengerModelEntityFromJson(response.data);

      if (isRefresh) {
        passengers = result.data;
      } else {
        passengers!.addAll(result.data!);
      }
      currentPage++;
      totalPages = result.totalPages!;
      print(response.data);
      setState(() {});

      return true;
    } else {
      return false;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("test future builder"),
      ),
      body: SmartRefresher(
        controller: refreshController,
        enablePullUp: true,
        onRefresh: () async {
          final result = await getPassengerData(isRefresh: true);
          if (result) {
            refreshController.refreshCompleted();
          } else {
            refreshController.refreshFailed();
          }
        },
        onLoading: () async {
          final result = await getPassengerData();
          if (result) {
            refreshController.loadComplete();
          } else {
            refreshController.loadFailed();
          }
        },
        child: ListView.separated(
            itemBuilder: (context, index) {
              final passenger = passengers![index];
              return ListTile(
                title: Text(passenger.name!),
                subtitle: Column(
                  children: [
                    Image(image: NetworkImage(passenger.airline![0].logo!), height: 30, width: 30, ),
                    Text(passenger.airline![0].country!)
                  ],
                ),
                trailing: Text(index.toString()),
              );
            },
            separatorBuilder: (context, index) => Divider(),
            itemCount: passengers!.length),
      ),
    );
  }
}

 

/// passenger_model_entity.dart

import 'dart:convert';
import 'package:abcworks/generated/json/base/json_field.dart';
import 'package:abcworks/generated/json/passenger_model_entity.g.dart';

@JsonSerializable()
class PassengerModelEntity {

	int? totalPassengers;
	int? totalPages;
	List<PassengerModelData>? data;
  
  PassengerModelEntity();

  factory PassengerModelEntity.fromJson(Map<String, dynamic> json) => $PassengerModelEntityFromJson(json);

  Map<String, dynamic> toJson() => $PassengerModelEntityToJson(this);

  @override
  String toString() {
    return jsonEncode(this);
  }
}

@JsonSerializable()
class PassengerModelData {

	@JSONField(name: "_id")
	String? sId;
	String? name;
	int? trips;
	List<PassengerModelDataAirline>? airline;
	@JSONField(name: "__v")
	int? iV;
  
  PassengerModelData();

  factory PassengerModelData.fromJson(Map<String, dynamic> json) => $PassengerModelDataFromJson(json);

  Map<String, dynamic> toJson() => $PassengerModelDataToJson(this);

  @override
  String toString() {
    return jsonEncode(this);
  }
}

@JsonSerializable()
class PassengerModelDataAirline {

	int? id;
	String? name;
	String? country;
	String? logo;
	String? slogan;
	@JSONField(name: "head_quaters")
	String? headQuaters;
	String? website;
	String? established;
  
  PassengerModelDataAirline();

  factory PassengerModelDataAirline.fromJson(Map<String, dynamic> json) => $PassengerModelDataAirlineFromJson(json);

  Map<String, dynamic> toJson() => $PassengerModelDataAirlineToJson(this);

  @override
  String toString() {
    return jsonEncode(this);
  }
}

 

 

 

https://pub.dev/packages/pull_to_refresh

 

pull_to_refresh | Flutter Package

a widget provided to the flutter scroll component drop-down refresh and pull up load.

pub.dev

 

728x90
반응형

'Flutter' 카테고리의 다른 글

[Flutter] 아이폰 빌드 / Developer Mode Disabled  (0) 2023.02.09
[Flutter] 윤년계산하기 - dart  (0) 2022.03.22
[Flutter] RxMap 사용  (0) 2022.01.20
[Flutter] Wrap, Chip, FlowLayout  (0) 2022.01.11
[Flutter ]textbuttonTheme  (0) 2022.01.11