下拉刷新指示器

RefreshIndicator 是下拉刷新指示器, 包装一个可滚动widget

示例:

import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
  
  createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage> {
  var list = [];
  int page = 0;
  bool isLoading = false; // 是否正在请求新数据
  bool showMore = false; // 是否显示底部加载中提示
  bool offState = false; // 是否显示进入页面时的圆形进度条
  ScrollController scrollController = ScrollController();
  
  void initState() {
    super.initState();
    // 监听滚动事件
    scrollController.addListener(() {
      // 是否滑动到了最底部: 当前位置为滚动的最大高度
      if (scrollController.position.pixels ==
          scrollController.position.maxScrollExtent) {
        setState(() {
          showMore = true;
        });
        getMoreData();
      }
    });
    getListData();
  }
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("RefreshIndicator"),
          ),
          body: Stack(
            children: <Widget>[
              RefreshIndicator(
                child: ListView.builder(
                  controller: scrollController,
                  itemCount: list.length + 1,//列表长度+底部加载中提示
                  itemBuilder: choiceItemWidget,
                ),
                onRefresh: _onRefresh,
              ),
              Offstage(
                offstage: offState,
                child: Center(
                  child: CircularProgressIndicator(),
                ),
              ),
            ],
          )
      ),
    );
  }
  
  void dispose() {
    super.dispose();
    // 手动停止滑动监听
    scrollController.dispose();
  }
  // 加载列表行组件
  Widget choiceItemWidget(BuildContext context, int position) {
    if (position < list.length) {
      return HomeListItem(position, list[position], (position) {
        debugPrint("点击了第$position条");
      });
    } else if (showMore) {
      return showMoreLoadingWidget();
    } else {
      return null;
    }
  }
  // 加载更多提示组件
  Widget showMoreLoadingWidget() {
    return Container(
      height: 50.0,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Text('加载中...', style: TextStyle(fontSize: 16.0),),
        ],
      ),
    );
  }
  // 模拟进入页面获取数据
  void getListData() async {
    if (isLoading) {
      return;
    }
    setState(() {
      isLoading = true;
    });
    await Future.delayed(Duration(milliseconds: 300), () {
      setState(() {
        isLoading = false;
        offState = true;
        list = List.generate(20, (i) {
          return ItemInfo("ListView的一行数据$i");
        });
      });
    });
  }
  // 模拟到底部加载更多数据
  void getMoreData() async {
    if (isLoading) {
      return;
    }
    setState(() {
      isLoading = true;
      page++;
    });
    await Future.delayed(Duration(milliseconds: 300), () {
      setState(() {
        isLoading = false;
        showMore = false;
        list.addAll(List.generate(3, (i) {
          return ItemInfo("上拉添加 $page : $i");
        }));
      });
    });
  }
  // 模拟下拉刷新
  Future < void > _onRefresh() async {
    if (isLoading) {
      return;
    }
    setState(() {
      isLoading = true;
      page = 0;
    });
    await Future.delayed(Duration(milliseconds: 300), () {
      setState(() {
        isLoading = false;
        List tempList = List.generate(3, (i) {
          return ItemInfo("下拉添加 $page : $i");
        });
        tempList.addAll(list);
        list = tempList;
      });
    });
  }
}
class ItemInfo {
  String title;
  ItemInfo(this.title);
}
// 定义一个回调接口
typedef OnItemClickListener = void Function(int position);
// ignore: must_be_immutable
class HomeListItem extends StatelessWidget {
  int position;
  ItemInfo iteminfo;
  OnItemClickListener listener;
  HomeListItem(this.position, this.iteminfo, this.listener);
  
  Widget build(BuildContext context) {
    var widget = Column(
      children: <Widget>[
        Container(
          child: Column(
            children: <Widget>[
              Row(
                children: <Widget>[
                  Text(
                    iteminfo.title,
                    style: TextStyle(
                      fontSize: 15.0,
                      color: Color(0xff999999),
                    ),
                  )
                ],
              ),
            ],
            mainAxisAlignment: MainAxisAlignment.center,
          ),
          height: 50.0,
          padding: EdgeInsets.only(left: 20.0),
        ),
        // 分割线
        Container(
          height: 1.0,
          color: Color.fromARGB(255, 230, 230, 230),
        )
      ],
    );
    // InkWell点击的时候有水波纹效果
    return InkWell(
      onTap: () => listener(position),
      child: widget
    );
  }
}

MIT Licensed | Copyright © 2018-present 滇ICP备16006294号

Design by Quanzaiyu | Power by VuePress