flutter下拉筛选组件_创建发布一个下拉刷新,上拉加载更多的flutter package

flutter create --template=package refresh_loadmore

用以上命令创建一个package包,refresh_loadmore是我的包名(先去https://pub.flutter-io.cn/上搜索一下你的包名,确保不会出现重名)。

编写包的实现

在lib/refresh_loadmore.dart中实现功能

library refresh_loadmore;

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

class RefreshLoadmore extends StatefulWidget {
  /// callback function on pull down to refresh | 下拉刷新时的回调函数
  final Future<void> Function() onRefresh;

  /// callback function on pull up to load more data | 上拉以加载更多数据的回调函数
  final Future<void> Function() onLoadmore;

  /// Whether it is the last page, if it is true, you can not load more | 是否为最后一页,如果为true,则无法加载更多
  final bool isLastPage;

  /// child widget | 子组件
  final Widget child;

  /// Prompt text when there is no more data at the bottom | 底部没有更多数据时的提示文字
  final String noMoreText;

  /// [noMoreText] text style | [noMoreText]的文字样式
  final TextStyle noMoreTextStyle;

  const RefreshLoadmore({
    Key key,
    @required this.child,
    @required this.isLastPage,
    this.noMoreText,
    this.noMoreTextStyle,
    this.onRefresh,
    this.onLoadmore,
  }) : super(key: key);
  @override
  _RefreshLoadmoreState createState() => _RefreshLoadmoreState();
}

class _RefreshLoadmoreState extends State<RefreshLoadmore> {
  final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
      GlobalKey<RefreshIndicatorState>();

  ScrollController _scrollController;
  bool _isLoading = false;

  @override
  void initState() {
    super.initState();
    _scrollController = ScrollController();
    _scrollController.addListener(() async {
      if (_scrollController.position.pixels >=
          _scrollController.position.maxScrollExtent) {
        if (_isLoading) {
          return;
        }

        setState(() {
          _isLoading = true;
        });

        if (widget.onLoadmore != null) {
          await widget.onLoadmore();
        }

        setState(() {
          _isLoading = false;
        });
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    Widget mainWiget = ListView(
      /// Solve the problem that there are too few items to pull down and refresh | 解决item太少,无法下拉刷新的问题
      physics: AlwaysScrollableScrollPhysics(),
      controller: _scrollController,
      children: <Widget>[
        widget.child,
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(16),
              child: _isLoading
                  ? CupertinoActivityIndicator()
                  : Text(
                      widget.isLastPage
                          ? widget.noMoreText ?? 'No more data'
                          : '',
                      style: widget.noMoreTextStyle ??
                          TextStyle(
                            fontSize: 18,
                            color: Theme.of(context).disabledColor,
                          ),
                    ),
            )
          ],
        )
      ],
    );

    if (widget.onRefresh == null) {
      return Scrollbar(child: mainWiget);
    }

    return RefreshIndicator(
      key: _refreshIndicatorKey,
      onRefresh: () async {
        if (_isLoading) return;
        await widget.onRefresh();
      },
      child: mainWiget,
    );
  }
}

创建一个example项目示例

在refresh_loadmore的根目录新建一个example项目

flutter create example

在example项目的pubspec.yaml中添加依赖

dependencies:
  refresh_loadmore:
    path: ../

在main.dart中编写示例代码

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.purple,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  bool isLastPage = false;

  /// is the last page | 是否为最后一页
  List list;
  int page = 1;

  @override
  void initState() {
    super.initState();
    loadFirstData();
  }

  Future<void> loadFirstData() async {
    await Future.delayed(Duration(seconds: 1), () {
      setState(() {
        list = [
          'dddd',
          'sdfasfa',
          'sdfgaf',
          'adsgafg',
          'dddd',
          'sdfasfa',
          'sdfgaf',
          'adsgafg',
          'dddd',
          'sdfasfa',
          'sdfgaf',
          'adsgafg'
          'adsgafg',
          'dddd',
          'sdfasfa',
          'sdfgaf',
          'adsgafg'
        ];
        isLastPage = false;
        page = 1;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: list != null
          ? RefreshLoadmore(
              onRefresh: loadFirstData,
              onLoadmore: () async {
                if (isLastPage) return;

                await Future.delayed(Duration(seconds: 1), () {
                  setState(() {
                    list.addAll(['123', '234', '457']);
                    page++;
                  });
                  print(page);
                  if (page >= 3) {
                    setState(() {
                      isLastPage = true;
                    });
                  }
                });
              },
              noMoreText: 'No more data, you are at the end',
              isLastPage: isLastPage,
              child: list.isNotEmpty
                  ? Column(
                      children: list
                          .map(
                            (e) => ListTile(
                              title: Text(e),
                              trailing: Icon(Icons.accessibility_new),
                            ),
                          )
                          .toList(),
                    )
                  : Center(
                      child: Text('empty'),
                    ),
            )
          : Center(child: CircularProgressIndicator()),
    );
  }
}

测试效果图如下:

dda8330999227d7c089872d131576673.png

1ef6b41e789eb6112958db0da0271405.png

52075dbccc38e8bba3e4df3dddfbb120.png

添加License和修改pubspec.yaml文件

修改包的LICENSE文件

MIT License

Copyright (c) 2020 shareven

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

修改pubspec.yaml

name: refresh_loadmore
description: A Flutter component that supports pull-down refresh and pull-up to load more data (一个组件,支持下拉刷新,上拉加载更多数据).
version: 1.0.1
homepage: https://github.com/shareven/refresh_loadmore
...

修改CHANGELOG.md

## [1.0.1] 

* initRelease

发布

发布前用命令检查

flutter pub pub publish --dry-run

发布

flutter pub publish
注意
如果是没有访问外国网站的,在 .bash_profile或.zprofile里面设置了 PUB_HOSTED_URLFLUTTER_STORAGE_BASE_URL 的记得注释掉这两个环境变量。
#export PUB_HOSTED_URL= https:// pub.flutter-io.cn
#export FLUTTER_STORAGE_BASE_URL= https:// storage.flutter-io.cn
flutter pub publish的时候要访问外国网站。请确保终端访问外国网站了。 (ping www.google.com)如果是通的,则可以执行。如果终端没有访问外国网站可以搜索一下 proxifier
但是我这还是失败了

3ef957ba5eebf960cff13a15d2abe9bb.png

更换另一个地址,又成功了

flutter packages pub publish --server=https://pub.dartlang.org

1745ba669d3c2a966b07f8807b5444fa.png

提升分数

上传之后发现分数好低

81d801fe442644f82a6bcf14cde7bc13.png

c181277e3a58e167e853c02a4bf90f0f.png

提示我pubspec.yaml的description包含太多中文了,那就把中文去掉吧

name: refresh_loadmore
description: A Flutter component that supports pull-down refresh and pull-up to load more data 
version: 1.0.2

homepage: https://github.com/shareven/refresh_loadmore
...

修改CHANGELOG.md

## [1.0.1] 

* initRelease

## [1.0.2] 

* remove Chinese description

重新发布

flutter pub pub publish --dry-run # 检查一下,没问题就发布
flutter packages pub publish --server=https://pub.dartlang.org

b1be5ec3a3a72870d717c9c5a8f02fe8.png

接下来就得靠各位读了本篇文章的观众大佬,点赞和下载使用,来提升分数了。感谢!感谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值