资讯专栏INFORMATION COLUMN

flutter实战3:解析HTTP请求数据和制作新闻分类列表

BicycleWarrior / 2437人阅读

摘要:当我们搭建好了整个的页面框架,现在我往页里加点东西各种分类的新闻列表。由于需要请求外部数据,因此引入一个较为方便的库。于是乎,在初始化对象时发起请求应该是个不错的办法具体是怎么初始化数据的,第三步会讲到,踩了不少坑。

当我们搭建好了整个APP的页面框架,现在我往Tab页里加点东西:各种分类的新闻列表。也可以参考我的Git,上面有要点注释。

由于需要请求外部数据,因此引入一个较为方便的http库。官方示例的httpClient也是可以的,但是坑略多,待会儿讲。

第一步

调整代码结构,定义一个Tab页内通用的列表对象,这种场景下使用ListView.builder()创建不定长度的列表:

//因为列表的长度不定,因此需要用有状态类来承载列表
class NewsList extends StatefulWidget{
  final String newsType;    //新闻类型
  @override
  NewsList({Key key, this.newsType} ):super(key:key);

  _NewsListState createState() => new _NewsListState();
}

class _NewsListState extends State{
  ...
  @override
  Widget build(BuildContext context){
    return new ListView.builder(        //ListView.builder非常适合用于创建不确定长度的的列表
        padding: const EdgeInsets.all(16.0),
        itemCount: data == null ? 0 : data.length,
        itemBuilder: (context, i) {
          return _newsRow(data[i]);//把数据项塞入ListView中
        }
      );
  }
  ...
}

Tab页的数据表达进行结构化处理,在最外层定义新闻Tab页的类,方便后面使用:

//定义TAB页对象,这样做的好处就是,可以灵活定义每个tab页用到的对象,可结合Iterable对象使用,以后讲
class NewsTab {
  String text;
  NewsList newsList;
  NewsTab(this.text,this.newsList);
}

_MyTabbedPageState对象中实例化这些Tab:

//将每个Tab页都结构化处理下,由于http的请求需要传入新闻类型的参数newsType,因此将新闻类型参数值作为对象属性传入Tab中
  final List myTabs = [
    new NewsTab("头条",new NewsList(newsType: "toutiao")),    //拼音就是参数值
    new NewsTab("社会",new NewsList(newsType: "shehui")),
    new NewsTab("国内",new NewsList(newsType: "guonei")),
    new NewsTab("国际",new NewsList(newsType: "guoji")),
    new NewsTab("娱乐",new NewsList(newsType: "yule")),
    new NewsTab("体育",new NewsList(newsType: "tiyu")),
    new NewsTab("军事",new NewsList(newsType: "junshi")),
    new NewsTab("科技",new NewsList(newsType: "keji")),
    new NewsTab("财经",new NewsList(newsType: "caijing")),
    new NewsTab("时尚",new NewsList(newsType: "shishang")),
  ];
第二步

由于重新了Tabs,原来的TabBar和TabBarView获取对应值的方式也发生了改变,用map+toList方法处理下:

@override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        backgroundColor: Colors.orangeAccent,
        title: new TabBar(
          controller: _tabController,
          tabs: myTabs.map((NewsTab item){      //NewsTab可以不用声明
            return new Tab(text: item.text==null?"错误":item.text);
          }).toList(),    //记住要用toList()转换一下map的结果,否则会由于类型不匹配而报错
          indicatorColor: Colors.white,
          isScrollable: true,   //水平滚动的开关,开启后Tab标签可自适应宽度并可横向拉动,并自动从左到右排列,默认关闭
        ),
      ),
      body: new TabBarView(
        controller: _tabController,
        children: myTabs.map((item) {
          return item.newsList; //使用参数值
        }).toList(),
      ),
    );
  }

以上对新闻页面的结构进行了重构,重头戏就是完善NewsList对象。于是乎,在初始化NewsList对象时发起HTTP请求应该是个不错的办法:

具体是怎么初始化数据的,第三步会讲到,踩了不少坑。这里的重点是,Flutter提倡数据驱动组件的创建,组件自己无法触发动态创建对象,只有通过数据绑定的方式,实现对象的重绘和动态加载,原理和react类似,比如:

第三步

到了这一步,完全进入踩坑模式。

踩坑1 http和httpclient都是IO异步操作,其内置的请求函数的返回值是Future类型对象,需要提前声明定义类型如:Future,返回值也需要await异步处理后才可以转换成需要的数据类型:

上图中列举了两种方法,建议使用下面那种,因为如果能从返回值中提取请求获取的数据,即可将所有的http请求封装到API文件中去,不必写在页面代码中,原因大家都懂的。
注意在setState()之前有一句if(!mounted) return,因为异步请求数据和控件的渲染是同时进行的,如果代码已经执行到了setState,但是数据还没有获取到,此时setState触发的控件渲染就会报错,为了避免这种空值错误,在setState之前先判断空间是否已经渲染完成,mountedFlutter内置的当前控件的状态标识,记住就好。

踩坑2 在ListView直属的Column里面不能用Expanded控件

图中的提示说使用Flexible控件更佳,然而实际上Flexible也会报错。报错的英文大概意思是ListView控件生成未知长度的列表时,总是会自动压缩每一个子元素的高度,而ExpandedFlexible都是可以自由伸缩的控件,造成ListView的子元素无法确定绘制的高度,为了使超出屏幕宽度的新闻标题自动换行,这个时候用ListTile顶替一下吧。

踩坑3 处理不同新闻图片数量不一致的问题

如上图,肯定是不行的,控件的子元素是不允许为空的,于是使用条件判断的方式封装一下:

踩坑3 深刻体会map数组和Object数组的使用,newsinfo.["title"]newsinfo.title两者的newsinfo类型是不一样的,详细还是到源码中去体会吧,注意对比newsinfomyTab这两个的用法。

这次页面写的非常辛苦,而且还没实现滚动刷新或顶部下拉刷新的效果,下一篇再更吧,还有很多要点我在源码中有标识,可以去我的Git中慢慢品味,今天就更到这里,滚去睡觉,真的来不起了。

感谢大家的支持,请关注我的Flutter圈子,多多投稿,也可以加入flutter 中文社区(官方QQ群:338252156)共同成长,谢谢大家~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93920.html

相关文章

  • flutter实战4:新闻列表的懒加载下拉手势刷新

    摘要:上一篇我们实现了新闻列表,但在网络不好的时候列表会白屏,因此为了提高使用体验,往列表中加入懒加载效果。其次,引入一个内置的手势控件,用于支持下拉刷新列表的效果如下图将异步执行也进行了控件化处理,即。 上一篇我们实现了新闻列表,但在网络不好的时候列表会白屏,因此为了提高使用体验,往列表中加入懒加载效果。其次,引入一个Flutter内置的手势控件,用于支持下拉刷新列表的效果如下图: sho...

    AlienZHOU 评论0 收藏0
  • 高级架构师实战:如何用最小的代价完成爬虫需求

    摘要:在系统正常运行时,可以变更爬虫的配置,一旦实时监控爬虫出现异常,可实时修正配置进行干预。从数据库中实时读取配置信息,响应业务层的配置请求。处理系统通过服务层,每次去取配置信息可能维护人员在实时修正及待抓取的列表进行处理。 showImg(https://segmentfault.com/img/bVLa4V?w=960&h=540); 一  缘起 在我工作的多家公司,有众多的领域,如房...

    light 评论0 收藏0
  • Flutter 专题】15 图解 ListView 异步加载数据与等待 #yyds干货盘点#

    摘要:小菜前两天再学时,整理了一下在列表中展示多种不同样式,今天继续深入学习异步请求数据并加载新闻列表以及初始进入页面的等小知识点。小菜刚接触时间不长,还有很多不清楚和不理解的地方,如果又不对的地方还希望多多指出。 小菜前两天再学 ListView 时,整理了一下在列表中展示多种不同 item 样式,今天继续深入学习...

    番茄西红柿 评论0 收藏2637
  • 性能优化全新思路!实践腾讯、字节、阿里、百度、网易等互联网公司项目实战+案例分析(附PDF源码)

    摘要:不努力不奋斗,可能就会在基层一辈子止步不前。不过,只一句,如果你还在做这一行,还是一名程序猿媛,想走上坡路的你,也许我这到手的十几家一线互联网公司性能优化项目实战可能会对你有所帮助。 ...

    ytwman 评论0 收藏0
  • Android程序员完全没时间提升自己怎么办?

    摘要:昨天有个小学弟给我发来微信,说他现在有点后悔选择开发了,月月光不说,还加班特别严重,平时也没有属于自己的时间去学习,问我刚毕业的时候是不是这样。每天回到出租屋都是倒头就睡,非常累,也没有其他时间提升自己的技术。 昨天有个小学弟给我发来微信,说他现在有点后悔选择Android开发了,月月光不说...

    kohoh_ 评论0 收藏0

发表评论

0条评论

BicycleWarrior

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<