专栏首页每天学点Android知识Flutter版本玩Android客户端(5)——微信公众号tab点击跳转

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

在Flutter版本玩Android客户端(4)——知识体系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很多地方用到,因此对其进行了封装,但是现在发现封装的还不够,应该将pulltorefresh一起加进去。

文章列表Widget的封装

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

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

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

本文分享自微信公众号 - 每天学点Android知识(android_every_day),作者:星风coder

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 在布局切换之间实现Transition动画

    同一个Activity之间,布局切换是可以有动画效果的,下面是仿照API Demo中的一个例子,如下图:

    用户1108631
  • TabLayout使用指南

    TabLayout是开发中经常使用到的控件,经常与ViewPager一起配合使用,一组tab,可以点击、可以滚动。这不,我们的app中也是用到了这个控件,之前对...

    用户1108631
  • 从0到1实现一个Android路由(1)——初探路由

    什么是路由?最初接触路由是在大学计算机网络中,网络层IP报文传输会涉及一个路由表的概念,路由表由源IP、目的IP组成,起始就是一个映射表。Android路由也是...

    用户1108631
  • python3报:ImportError: No module named 'MySQLdb'

    项目在转到python3.6时,原先的导入MySQLdb模块都提示无法导入,pip install mysqldb也安装失败。 问题原因: python2和...

    墨文
  • Java基础-07(01).总结private,this,封装,static,成员方法变量,局部变量匿名对象

    1:成员变量和局部变量的区别(理解) (1)在类中的位置不同 成员变量:类中方法外 局部变量:方法定义中或者方法声明上 (2)在内存中的位置不同 成...

    奋斗蒙
  • 学会如何让你在网络上变的相对匿名

    因为最近在弄渗透测试,就担心那天被查水表了,就想起怎么让自己的变的相对匿名呢,这时我想到了tor,“Tor(The Onion Router)是第二代洋葱...

    用户3170383
  • 设计模式(一),创建模式

    1、工厂模式 通过工厂类,创建不同的对象。工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。

    写PHP的老王
  • 错误cron导致linux宕机 原

    MAILTO是针对用户配置的,于是将该参数加入/var/spool/cron/internal下;

    阿dai学长
  • 深度 | 从概念到实践,我们该如何构建自动微分库

    机器之心
  • 智能云上手指南:实时流式语音识别 iOS SDK

    本文将为大家讲解如何上手腾讯云提供的智能语音识别服务中的实时流式语音识别,主要是 iOS 开发 SDK 的一些使用经验。

    云加社区专栏

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动