Flutter版本玩Android客户端(5)——微信公众号tab点击跳转

Flutter版本玩Android客户端(4)——知识体系tab点击跳转中,完成了主页面知识体系tab的点击跳转,本文主要完成微信公众号tab的跳转。效果如下:
微信tab的跳转

微信tab的跳转

微信tab的跳转后也是一个文章列表,复用ArticleList这个Widget。
代码如下:

class _WeChatArticleListWidgetState extends State<WeChatArticleListWidget>
    with SingleTickerProviderStateMixin {
  RefreshController _refreshController = RefreshController();

  WeChatItem _weChatItem;

  List<ArticleItem> _articleItem = List();

  int curPage = 0;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _weChatItem = ModalRoute.of(context).settings.arguments as WeChatItem;
    _onRefresh();
  }

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

  void _onRefresh() async {
    curPage = 0;
    ApiClient apiClient = ApiClient.getInstance();
    apiClient
        .getResponse(
            "https://wanandroid.com/wxarticle/list/${_weChatItem.id}/$curPage/json")
        .then((val) {
      ArticleList articleList = ArticleList.fromJson(val);
      if (articleList.errorCode < 0) {
        setState(() {
          _refreshController.refreshFailed();
        });
      } else {
        curPage++;
        _articleItem.clear();
        _articleItem.addAll(articleList.data.datas);
        setState(() {
          _refreshController.refreshCompleted();
        });
      }
    });
  }

  void _onLoading() async {
    ApiClient apiClient = ApiClient.getInstance();
    apiClient
        .getResponse(
            "https://wanandroid.com/wxarticle/list/${_weChatItem.id}/$curPage/json")
        .then((val) {
      ArticleList articleList = ArticleList.fromJson(val);
      if (articleList.errorCode < 0) {
        setState(() {
          _refreshController.loadFailed();
        });
      } else {
        _articleItem.addAll(articleList.data.datas);
        setState(() {
          if (articleList.data.datas.length == 0) {
            _refreshController.loadNoData();
          } else {
            _refreshController.loadComplete();
            curPage++;
          }
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_weChatItem.name),
        leading: IconButton(
            icon: Icon(Icons.arrow_back),
            onPressed: () {
              Navigator.of(context).pop();
            }),
      ),
      body: SmartRefresher(
        controller: _refreshController,
        header: WaterDropHeader(),
        footer: ClassicFooter(),
        onRefresh: _onRefresh,
        onLoading: _onLoading,
        enablePullDown: true,
        enablePullUp: true,
        child: CustomScrollView(
          slivers: <Widget>[ArticleListWidget(_articleItem)],
        ),
      ),
    );
  }
}

思考:之前由于文章列表这个Widget很多地方用到,因此对其进行了封装,但是现在发现封装的还不够,应该将pull_to_refresh一起加进去。

文章列表Widget的封装

文章列表是一个支持下拉刷新、上拉加载的控件;知识体系item和tab、微信公众号都用到了,唯一不同的是URL的拼凑;因此可以将其进一步封装,URL的组装由外部每个用到的地方控制。

而首页的文章列表是和banner一起refresh的,因此在之前ArticleListWidget基础上增加了pull_to_refresh的功能,代码如下:

class PullToRefreshArticleListWidget extends StatefulWidget {
  UrlFactory _urlFactory;

  PullToRefreshArticleListWidget(this._urlFactory);

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

class _PullToRefreshArticleListWidgetState
    extends State<PullToRefreshArticleListWidget>
    with SingleTickerProviderStateMixin {
  final RefreshController _refreshController = RefreshController();

  List<ArticleItem> _articleList = [];

  int curPage = 0;

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

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

  void _onRefresh() async {
    curPage = 0;
    ApiClient apiClient = ApiClient.getInstance();
    apiClient.getResponse(widget._urlFactory.getUrl(curPage)).then((val) {
      ArticleList list = ArticleList.fromJson(val);
      if (list.errorCode < 0) {
        setState(() {
          _refreshController.refreshFailed();
        });
      } else {
        curPage++;
        _articleList.clear();
        _articleList.addAll(list.data.datas);
        setState(() {
          _refreshController.refreshCompleted();
        });
      }
    });
  }

  void _onLoad() async {
    ApiClient apiClient = ApiClient.getInstance();
    apiClient.getResponse(widget._urlFactory.getUrl(curPage)).then((val) {
      ArticleList list = ArticleList.fromJson(val);
      if (list.errorCode < 0) {
        setState(() {
          _refreshController.loadFailed();
        });
      } else {
        _articleList.addAll(list.data.datas);
        setState(() {
          if (list.data.datas.length == 0) {
            _refreshController.loadNoData();
          } else {
            curPage++;
            _refreshController.refreshCompleted();
          }
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return SmartRefresher(
      controller: _refreshController,
      header: WaterDropHeader(),
      footer: ClassicFooter(),
      onRefresh: _onRefresh,
      onLoading: _onLoad,
      enablePullDown: true,
      enablePullUp: true,
      child: CustomScrollView(
        slivers: <Widget>[ArticleListWidget(_articleList)],
      ),
    );
  }
}

URL的拼接是通过接口的方式提供的,每个Widget提供URL的拼接。测试发现,效果妥妥的。

关于代码,参考:
https://github.com/wangli135/wan_android/tree/ac6ed35f29c9ba8edc909461bade089dd75df615

关注我的技术公众号,不定期会有技术文章推送,不敢说优质,但至少是我自己的学习心得。微信扫一扫下方二维码即可关注:
二维码

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页