Flutter 实现下拉刷新&上拉加载(包含网络请求)

实现功能

  1. 支持调用接口调用,分页加载
  2. 支持下拉刷新

效果图

使用方法

  1. 添加依赖
dependencies:
  pull_to_refresh: ^1.5.7
  dio: 3.0.7
  fluttertoast: ^3.1.0

2.主界面

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

import 'ApiServices.dart';
import 'ArticleBeans.dart';
import 'ArticleItem.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ArticleScreen(408),
    );
  }
}

class ArticleScreen extends StatefulWidget {
  final int id;

  ArticleScreen(this.id);

  @override
  State createState() {
    return new ArticleScreenState();
  }
}

class ArticleScreenState extends State
    with AutomaticKeepAliveClientMixin {
  List _articleList = new List();

  ScrollController _scrollController = new ScrollController();

  int _page = 1;

  RefreshController _refreshController =
      new RefreshController(initialRefresh: true);

  Future getArticleList() async {
    _page = 1;
    int _id = widget.id;
    apiService.getArticleList((ArticleModel articleModel) {
      if (articleModel.isSuccess()) {
        _refreshController.refreshCompleted(resetFooterState: true);
        setState(() {
          _articleList.clear();
          _articleList.addAll(articleModel.data.datas);
        });
      } else {
        Fluttertoast.showToast(msg: articleModel.errorMsg);
      }
    }, (DioError error) {}, _id, _page);
  }

  Future getMoreArticleList() async {
    _page++;
    int _id = widget.id;
    apiService.getArticleList((ArticleModel articleModel) {
      if (articleModel.isSuccess()) {
        if (articleModel.data.datas.length > 0) {
          _refreshController.loadComplete();
          setState(() {
            _articleList.addAll(articleModel.data.datas);
          });
        } else {
          _refreshController.loadNoData();
        }
      } else {
        _refreshController.loadFailed();
        Fluttertoast.showToast(msg: articleModel.errorMsg);
      }
    }, (DioError error) {
      _refreshController.loadFailed();
    }, _id, _page);
  }

  @override
  bool get wantKeepAlive => true;

  @override
  void dispose() {
    _refreshController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    getArticleList();
    _scrollController.addListener(() {
      /// 滑动到底部,加载更多
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        getMoreArticleList();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      body: SmartRefresher(
        enablePullDown: true,
        enablePullUp: true,
        header: MaterialClassicHeader(),
        controller: _refreshController,
        onRefresh: getArticleList,
        onLoading: getMoreArticleList,
        child: ListView.builder(
          itemBuilder: itemView,
          physics: new AlwaysScrollableScrollPhysics(),
          controller: _scrollController,
          itemCount: _articleList.length,
        ),
      ),
    );
  }

  Widget itemView(BuildContext context, int index) {
    return ItemArticleList(item: _articleList[index]);
  }
}

3.单行item

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

import 'ArticleBeans.dart';

class ItemArticleList extends StatefulWidget {
  ArticleBean item;

  ItemArticleList({this.item});

  @override
  State createState() {
    return new ItemArticleListState();
  }
}

class ItemArticleListState extends State {
  @override
  Widget build(BuildContext context) {
    var item = widget.item;
    return InkWell(
      onTap: () {
        Fluttertoast.showToast(msg: item.title);
      },
      child: Column(
        children: [
          Container(
            padding: EdgeInsets.fromLTRB(16, 10, 16, 10),
            child: Row(
              children: [
                Expanded(
                  child: Text(
                    item.title,
                    maxLines: 2,
                    style: TextStyle(
                      fontSize: 16,
                    ),
                    textAlign: TextAlign.left,
                  ),
                )
              ],
            ),
          ),
          Divider(height: 1),
        ],
      ),
    );
  }

}

  1. 网络请求
import 'package:dio/dio.dart';

import 'ArticleBeans.dart';

ApiService _apiService = new ApiService();

ApiService get apiService => _apiService;

class ApiService {
  Dio dio = Dio();

  /// 获取公众号文章列表数据
  void getArticleList(
      Function callback, Function errorCallback, int _id, int _page) async {
    String baseUrl = "https://www.wanandroid.com/wxarticle/list";
    dio.get(baseUrl + "/$_id/$_page/json").then((response) {
      callback(ArticleModel.fromJson(response.data));
    }).catchError((e) {
      errorCallback(e);
    });
  }
}

完整源代码

https://gitee.com/cxyzy1/flutter_pulldown_refresh/tree/master/pulldown_refresh_with_network

你可能感兴趣的:(Flutter 实现下拉刷新&上拉加载(包含网络请求))