前言

紧接上文界面篇,上文中在构建布局的时候因为是直接将文字图片显示出来的,所以消息类Message,和日知录类One都是采用的无状态的StatelessWidget类,这次我们需要调用接口,然后将返回的数据动态的显示到那两个控件上去,StatelessWidget类已经无法满足需求了,这个时候我们需要使用Flutter提供的另一个类StatefulWidget,一旦控件继承了这个类则说明该空间是一个有状态的控件,可以进行动态更新等。

  • 推荐阅读: 《StatefulWidget》, 《State.setState》,《为您的Flutter应用程序添加交互》

到目前为止,我们只使用了无状态的widget。无状态widget从它们的父widget接收参数, 它们被存储在final型的成员变量中。 当一个widget被要求构建时,它使用这些存储的值作为参数来构建widget。 为了构建更复杂的体验 - 例如,以更有趣的方式对用户输入做出反应 - 应用程序通常会携带一些状态。 Flutter使用StatefulWidget来满足这种需求。StatefulWidget是特殊的widget,它知道如何生成State对象,然后用它来保持状态。

解析

那么该如何创建一个有状态的widget,同时又如何进行网络请求并对控件的状态进行更新呢?我们一个一个的解决。

  1. 创建一个有状态的Message控件
//消息
class Message extends StatefulWidget {@overrideMessageState createState() => new MessageState();
}class MessageState extends State<Message> {@overrideWidget build(BuildContext context) {//这里创建页面}
}
复制代码

build函数的内容其实和之前创建无状态的Message控件的是一样的,直接复制来就好

@overrideWidget build(BuildContext context) {return new Padding(padding: new EdgeInsets.all(18.0),child: new Column(children: <Widget>[new Container(child: new Row(children: <Widget>[new Icon(Icons.message,color: Colors.black26,size: 17.0,),new Container(margin: new EdgeInsets.only(left: 5.0),child: new Text('消息',style: new TextStyle(color: Color(0xFF888888)),),)],),),new Divider(color: Color(0xFF888888),),new Container(margin: new EdgeInsets.all(10.0),child: new Text("这里是消息"),),new Divider(color: Color(0xFF888888),)],),);}
复制代码
  1. 进行网络请求并更新控件 在flutter中进行网络请求有两种方式
  • 在Flutter中发起HTTP网络请求
  • 开源库——dio 在这里推荐使用第二种,dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时等。和安卓里的OkHttp类似。具体用法可以查看传送门,文档写的很详细。 回到该应用,在这里我们需要创建一个getMessage()方法,并通过get请求相应的接口,然后对返回的res进行解析即可,如下所示:
  String message = "这里是消息模块";@overridevoid initState() {super.initState();getMessage();}//获取消息void getMessage() {Dio().get(Constant.GET_MSG).then((res) {if (res.statusCode == 200) {int code = res.data['code'];if (code == 200) {String info = res.data['info'][0];print(info);setState(() {message = info;});}}});}
复制代码

说明一下:

  1. 调用setState()是至关重要的,因为它告诉框架控件的状态已经改变,控件应该重新绘制。在这里的作用就是将之前设置的message变量变为从接口中获取的变量。
  2. json的解析,推荐阅读《在 Flutter 中解析复杂的 JSON》
  3. 我们如果需要在控件一开始渲染的时候就要发送网络请求,需要在initState()函数中调用getMessage()方法

该页代码

因为日知录部分的基本上也是网络请求和动态渲染控件,道理是一致的,所以我就直接在这里贴上代码了。

import 'package:flutter/material.dart';
import 'package:flutter_guohe/common/eventBus.dart';
import 'package:dio/dio.dart';
import 'package:flutter_guohe/views/customview.dart';
import 'package:flutter_guohe/utils/constant.dart';class Today extends StatefulWidget {@overrideTodayState createState() => new TodayState();
}class TodayState extends State<Today> {//打开drawervoid openDrawer() {eventBus.fire(new EventOpenDrawer(true));}@overrideWidget build(BuildContext context) {return new MaterialApp(home: new Scaffold(appBar: new AppBar(leading: new IconButton(icon: Icon(Icons.home),onPressed: () {//打开draweropenDrawer();},),title: new Text("今日"), //设置标题内容backgroundColor: Color.fromARGB(255, 119, 136, 213), //设置appbar背景颜色centerTitle: true, //设置标题是否局中),body: new ListView(children: <Widget>[new Header(), //头部new BigDivider(),new TodayKb(), //今日课表new BigDivider(),new Message(), //消息new BigDivider(),new One() //日知录],),),);}
}//首页的头部信息
class Header extends StatelessWidget {@overrideWidget build(BuildContext context) {return new Container(height: 100.0,margin: new EdgeInsets.all(8.0),child: new Row(children: <Widget>[new Expanded(child: new Column(children: <Widget>[//头像new Container(width: 60.0,height: 60.0,margin: new EdgeInsets.all(8.0),decoration: BoxDecoration(image: DecorationImage(image: new AssetImage('assets/imgs/ic_menu_score.png'),//从Assets加载图片fit: BoxFit.cover,),shape: BoxShape.circle,),),new Text('查成绩',textAlign: TextAlign.center,)],),flex: 1,),new Expanded(child: new Column(children: <Widget>[//头像new Container(width: 60.0,height: 60.0,margin: new EdgeInsets.all(8.0),decoration: BoxDecoration(image: DecorationImage(image: new AssetImage('assets/imgs/ic_menu_pe.png'),//从Assets加载图片fit: BoxFit.cover,),shape: BoxShape.circle,),),new Text('查体育',textAlign: TextAlign.center,)],),flex: 1,),new Expanded(child: new Column(children: <Widget>[//头像new Container(width: 60.0,height: 60.0,margin: new EdgeInsets.all(8.0),decoration: BoxDecoration(image: DecorationImage(image: new AssetImage('assets/imgs/ic_menu_bus.png'),//从Assets加载图片fit: BoxFit.cover,),shape: BoxShape.circle,),),new Text('查校车',textAlign: TextAlign.center,)],),flex: 1,),new Expanded(child: new Column(children: <Widget>[//头像new Container(width: 60.0,height: 60.0,margin: new EdgeInsets.all(8.0),decoration: BoxDecoration(image: DecorationImage(image: new AssetImage('assets/imgs/ic_menu_system.png'),//从Assets加载图片fit: BoxFit.cover,),shape: BoxShape.circle,),),new Text('校园系统',textAlign: TextAlign.center,)],),flex: 1,),new Expanded(child: new Column(children: <Widget>[//头像new Container(width: 60.0,height: 60.0,margin: new EdgeInsets.all(8.0),decoration: BoxDecoration(image: DecorationImage(image: new AssetImage('assets/imgs/ic_menu_more.png'),//从Assets加载图片fit: BoxFit.cover,),shape: BoxShape.circle,),),new Text('更多',textAlign: TextAlign.center,)],),flex: 1,),],),);}
}//今日课表
class TodayKb extends StatefulWidget {@overrideTodayKbState createState() => new TodayKbState();
}class TodayKbState extends State<TodayKb> {@overrideWidget build(BuildContext context) {//跳转至课表_toKb() {print('跳转至课表');}return new Padding(padding: new EdgeInsets.all(18.0),child: new Column(children: <Widget>[new Container(child: new Row(children: <Widget>[new Icon(Icons.camera,color: Colors.black26,size: 17.0,),new Container(margin: new EdgeInsets.only(left: 5.0),child: new Text('今日课表',style: new TextStyle(color: Color(0xFF888888)),),)],),),new Divider(color: Color(0xFF888888),),new Container(margin: new EdgeInsets.only(top: 30.0, bottom: 2.0),child: new Text("今天居然没有课~" + "\uD83D\uDE01"),),new GestureDetector(child: new Container(margin: new EdgeInsets.only(top: 30.0, bottom: 2.0),child: new Text('点我查看完整课表',style: new TextStyle(color: Color(0xFF888888,),fontSize: 12.0)),),onTap: _toKb,),],),);}
}//消息
class Message extends StatefulWidget {@overrideMessageState createState() => new MessageState();
}class MessageState extends State<Message> {String message = "这里是消息模块";@overridevoid initState() {super.initState();getMessage();}//获取消息void getMessage() {Dio().get(Constant.GET_MSG).then((res) {if (res.statusCode == 200) {int code = res.data['code'];if (code == 200) {String info = res.data['info'][0];print(info);setState(() {message = info;});}}});}@overrideWidget build(BuildContext context) {return new Padding(padding: new EdgeInsets.all(18.0),child: new Column(children: <Widget>[new Container(child: new Row(children: <Widget>[new Icon(Icons.message,color: Colors.black26,size: 17.0,),new Container(margin: new EdgeInsets.only(left: 5.0),child: new Text('消息',style: new TextStyle(color: Color(0xFF888888)),),)],),),new Divider(color: Color(0xFF888888),),new Container(margin: new EdgeInsets.all(10.0),child: new Text(message),),new Divider(color: Color(0xFF888888),)],),);}
}//日知录
class One extends StatefulWidget {@overrideOneState createState() => new OneState();
}class OneState extends State<One> {String date = "2018/09/14";String imgUrl = 'http://image.wufazhuce.com/Fn5E1UnrcvN0jwFRiOtDZ2WnQa4N';String imgAuthor = "Fahmi Ramadhan";String imgKind = "摄影";String url = "http://m.wufazhuce.com/one/2202";String word = "恋爱不是用谈的,是坠入的。";String wordFrom = "《寂寞东京铁塔》";//获取日知录的内容void getOneContent() {FormData formData = new FormData.from({"TransCode": "030111", "OpenId": "123456789", "Body": "123456789"});Dio().post(Constant.ONE, data: formData).then((res) {setState(() {date = res.data['Body']['date'].toString().split(" ")[0].replaceAll("-", "/");imgUrl = res.data['Body']['img_url'];imgAuthor = res.data['Body']['img_author'];imgKind = res.data['Body']['img_kind'];url = res.data['Body']['url'];word = res.data['Body']['word'];wordFrom = res.data['Body']['word_from'];});});}@overridevoid initState() {// TODO: implement initStatesuper.initState();getOneContent();}@overrideWidget build(BuildContext context) {return new Padding(padding: new EdgeInsets.all(18.0),child: new Column(children: <Widget>[new Container(child: new Row(children: <Widget>[new Icon(Icons.email,color: Colors.black26,size: 17.0,),new Container(margin: new EdgeInsets.only(left: 5.0),child: new Text('日知录',style: new TextStyle(color: Color(0xFF888888)),),)],),),new Divider(color: Color(0xFF888888),),new Container(margin: new EdgeInsets.all(10.0),child: new Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[new Text(date,style: new TextStyle(color: Color(0xFF888888)),),new Margin(indent: 6.0),new Image(image: new NetworkImage(imgUrl)),new Margin(indent: 6.0),new Text(imgAuthor + " | " + imgKind,style: new TextStyle(color: Color(0xFF888888)),),new Margin(indent: 6.0),new Text(word,textAlign: TextAlign.center,style: new TextStyle(color: Color(0xFF888888)),),new Margin(indent: 6.0),new Text(wordFrom,style: new TextStyle(color: Color(0xFF888888)),)],),),new Divider(color: Color(0xFF888888),)],),);}
}
复制代码

利用Flutter写一个跨平台的果核APP(3)——网络请求相关推荐

  1. 利用Flutter写一个跨平台的果核APP(4)——数据存储

    前言 目前我们已经实现了几个界面,今天这篇文章开始着手进行登录页的制作,主要流程就是获取输入框中的内容,发送给后台进行验证,如果成功将返回信息保存在本地并跳转至首页,如果失败就提示用户重新输入. 在这 ...

  2. 利用Flutter写一个跨平台的果核APP(0)——介绍

    前言 今年2月的时候,Google在开发者大会上推出了flutter的第一个预览版,我是在3月左右的时候才了解到这个全新的跨平台框架,并在阅读了相关文档之后写了一篇<你好,Flutter> ...

  3. 利用Flutter写一个跨平台的果核APP(1)——界面篇1

    前言 从这里开始,我就准备边学边做边用博客记录下自己的重构历程,会结合已有的app的样式进行重构. 原图 先看一下app的截图: 上面两个截图是app的首页和左侧菜单栏的截图,首页下方是一个可以滑动的 ...

  4. 用 Flutter 写一个精美的登录页面(最新版)

    用 Flutter 写一个精美的登录页面(最新版) 主体结构 标题 输入框 登录按钮 其他登录方式 注册按钮 完整源码 参考了博客:用flutter写一个精美的登录页面.但是那篇文章是 18 年的,较 ...

  5. 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装

    在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...

  6. 利用python写一个简单的双色球彩票系统

    利用python写一个简单的双色球彩票系统 1.设置每次买的号码一样 写一个双色球彩票系统,系统可以随机产生一组数据,一组彩票数据有六位数,这六位数的的取值范围是0和1. 一张彩票是两块钱,用户可以选 ...

  7. python抽奖游戏_利用Python写一个抽奖程序,解密游戏内抽奖的秘密

    原标题:利用Python写一个抽奖程序,解密游戏内抽奖的秘密 前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 极客 ...

  8. 利用Cocos2d-x写一个程序读取传奇wzl文件

    Cocos2d-x是一个用于游戏开发的开源框架,它提供了用于制作2D游戏的工具和功能.若要利用Cocos2d-x读取传奇wzl文件,需要对wzl文件的格式进行分析,并使用Cocos2d-x提供的读取文 ...

  9. 利用itchat写一个聊天机器人

    利用itchat写一个聊天机器人 聊天机器人 图灵机器人 需要的库 **自动回复私聊消息** **自动回复群聊消息** 结语: 聊天机器人 偶然在CSDN上看到大佬用20行教你写一个聊天机器人,觉得甚 ...

最新文章

  1. DCN-s4600 跨vlan访问
  2. this指向总结(无栗子)
  3. 基于TCP协议的socket通信
  4. golang使用gdb
  5. 架构设计-业务逻辑层简述
  6. 绘图: Python matplotlib简介
  7. 洛谷1052——过河(DP+状态压缩)
  8. alsa声音编程介绍
  9. 主机关机后第二天就无法开机_iphone没电自动关机后无法充电和开机的解决办法!(亲身经历)...
  10. ios URLSchemes
  11. mysql主从复制延迟问题的相关知识与解决方案
  12. (转发)详解汽车UDS诊断协议(一)
  13. 小米6显示服务器出错,小米6解锁BL显示未连接手机解决办法以及各种小技巧汇总......
  14. nodejs ffi调用C++dll动态库 ffi调用语法
  15. 正则表达式中的前瞻,后顾,负前瞻,负后顾
  16. Sparkplug规范-4.引用标准和资源
  17. 【毕业设计】基于STM32的宠物自动喂食装置
  18. UIPresentationController 教程:入门
  19. Java后端面试(五)
  20. PLC伺服走位(三菱FX5UPLC伺服控制)

热门文章

  1. sybase数据库导出mysql_使用BCP从Sybase远程数据库中导出数据
  2. android 编译之后黑屏_抖音BoostMultiDex:Android低版本上首次启动时间减少80%(一)...
  3. 不使用注解和使用注解的web-service-dao结构
  4. Min_25 筛小结
  5. 图片在线转换base64
  6. c#和WIN32 调用
  7. UrlReWriter 使用经验小结
  8. ASP.NET 2.0 中的新增服务、控件与功能概述(四)
  9. 小贝拉机器人是朋友_报废机器人应该属于什么垃圾?《宝莱坞机器人2.0》给你答案...
  10. java ndk 在哪_NDK简介