天天看點

flutter 上拉重新整理,下拉加載更多拉重新整理頁面内容,下拉加載更多功能

拉重新整理頁面内容,下拉加載更多功能

import 'package:flutter/material.dart';
import 'package:zetc_app/constants.dart';

/**
 * 帶上拉重新整理和下拉加載的listView
 */
class RefreshListView extends StatefulWidget {
  RefreshListView({
    // 重新加載函數
    this.reload,
    // 清單資料
    this.dataList,
    // 頁面資料
    this.pageData,
    // 生成每一行的樣式函數
    this.itemRow,
    // 内容高度
    this.height,
    // 背景顔色
    this.bgColor,
    // 翻頁參數
    this.page,
    // 是否加載完全部資料
    this.isLoadedAll,
  });
  final reload;
  final dataList;
  final pageData;
  final itemRow;
  final double height;
  final int page;
  final bool isLoadedAll;
  final Color bgColor;
  @override
  _RefreshListViewState createState() => _RefreshListViewState();
}

class _RefreshListViewState extends State<RefreshListView> {
  // 滾動控制器
  ScrollController _scrollController = new ScrollController();
  // 是否正在加載中
  bool isLoading = false;
  @override
  void initState() {
    super.initState();

    // 添加事件
    _scrollController.addListener(() {
      // 目前位置資訊
      var position = _scrollController.position;
      // 小于50px時,觸發上拉加載;
      if (position.maxScrollExtent - position.pixels < 50) {
        if (!widget.isLoadedAll && !isLoading) {
          isLoading = true;
          // 加載更多方法
          widget.reload(widget.page,(){
            isLoading = false;
          });
        }
      }
    });
  }

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

  /**
   * 上拉重新整理方法
   */
  Future<void> _onRefresh() async {
    await widget.reload(1,(){});
  }

  Widget _getRow(BuildContext context, int index) {
    if (index < widget.dataList.length) {
      return widget.itemRow(context, index, widget.dataList);
    }
    return _getMoreWidget();
  }

  Widget _getMoreWidget() {
    if (widget.isLoadedAll) {
      return Center(
        child: Padding(
          padding:
              EdgeInsets.symmetric(vertical: Constants().h20, horizontal: 0),
          child: Text(
            widget.dataList.length>0?'已加載完全部資料':'暫無資料!',
            style: TextStyle(fontSize: Constants().sp28),
          ),
        ),
      );
    } else {
      return Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            SizedBox(
              width: Constants().w40,
              height: Constants().w40,
              child: CircularProgressIndicator(
                strokeWidth: Constants().w2,
                valueColor: AlwaysStoppedAnimation<Color>(
                    Constants().defaultBtnBgColor),
              ),
            ),
            Padding(
              padding: EdgeInsets.symmetric(
                  vertical: Constants().h10, horizontal: Constants().w30),
              child: Text(
                '加載中...',
                style: TextStyle(fontSize: Constants().sp28),
              ),
            ),
          ],
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        height: widget.height ?? double.infinity,
        color: widget.bgColor ?? Colors.white,
        child: RefreshIndicator(
            color: Constants().defaultFontColor,
            backgroundColor: Colors.white,
            child: widget.dataList.length == 0
                ? _getMoreWidget()
                : ListView.builder(
                    controller: _scrollController,
                    itemCount: widget.dataList.length == 0
                        ? 0
                        : widget.dataList.length + 1,
                    itemBuilder: (context, index) {
                      return _getRow(context, index);
                    },
                  ),
            onRefresh: _onRefresh));
  }
}
           

使用方式:

// 引入上面的檔案類
import 'package:demo_app/components/refrest_list_view.dart';
// 省略其他不相關代碼...

// 定義參數
List dataList = [];
int page = 1;
int pageSize = 6;
bool isLoadedAll = false;
bool noData = false;


  _getData(int currentPageIndex,callback) {
    ApiRequestUtil.getCoinOutLog(currentPageIndex, pageSize, {
      "context": context,
      "success": (res) {
        callback();
        if (mounted) {
          setState(() {
            if(currentPageIndex == 1){
              dataList = res["data"]["data"];
            }else{
              dataList.addAll(res["data"]["data"]);
            }
            var currentPage = int.parse(res["data"]["current_page"].toString());
            var lastPage = int.parse(res["data"]["last_page"].toString());
            if (currentPage >= lastPage) {
              isLoadedAll = true;
            } else {
              isLoadedAll = false;
              page = currentPageIndex + 1;
            }
          });
        }
      },
      "fail": () {
        setState(() {
          noData = true;
        });
      }
    });
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _getData(1,(){});
  }

// 無資料的情況下的顯示方式
Widget _noData() {
    return Center(
      child: Text("暫無記錄!", style: TextStyle(fontSize: Constants().sp28)),
    );
  }
// 每一行生成的函數
Widget _itemRow(BuildContext context, int index, List dataList) {
    return GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: () {
          // 跳轉到公告詳情頁面
        },
        child: Container(
            // 行的内容自定義
        )  
    );
}

@override
  Widget build(BuildContext context) {
    return Scaffold(
        body: noData
            ? _noData()
            : RefreshListView(
                reload: _getData,
                isLoadedAll: isLoadedAll,
                page: page,
                dataList: dataList,
                itemRow: _itemRow,
              )
        );
  }
}
           

歡迎加群讨論更多flutter相關問題(7天有效)如果失效,可加個人微信拉群

flutter 上拉重新整理,下拉加載更多拉重新整理頁面内容,下拉加載更多功能
flutter 上拉重新整理,下拉加載更多拉重新整理頁面内容,下拉加載更多功能