内容简介:首先要在然后进行跳转
Flutter
的页面跳转,主要是通过 Navigator
来实现,类似原生中的路由,分为静态和动态2种方式。
- 静态
首先要在 MaterialApp
的 routes
中进行注册
MaterialApp( routes: { 'base': (BuildContext context) { return BaseDemo(); }, 'login': (BuildContext context) { return LoginDemo(); } }, title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.brown, ), home: MainDemo(), ); 复制代码
然后进行跳转
RaisedButton( child: Text('BaseWidget'), onPressed: () { Navigator.pushNamed(context, 'base'); }, ) 复制代码
这种方式的缺点也比较明显,首先需要注册,其次是不能传递参数
- 动态
需要构建 MaterialPageRoute
RaisedButton( child: Text('PageView'), onPressed: () { Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context) { return PageViewDemo(); })); }, ) 复制代码
- 关闭页面
主要是通过 pop
方法来实现 Navigator.of(context).pop();
- 传递参数
首先,需要在目标 Widget
中定义参数
class LoginDemo extends StatefulWidget { @override _LoginDemoState createState() => _LoginDemoState(tel); final String tel; LoginDemo({Key key, @required this.tel}) : super(key: key); } 复制代码
再传递参数
RaisedButton( child: Text('Login'), onPressed: () { Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context) { return LoginDemo(tel: '18700000000'); })); }, ) 复制代码
目标 Widget
取值,这里用到的是上一篇中的登录示例,详情可以查看 【Flutter】开发之高级Widget(三)
class _LoginDemoState extends State<LoginDemo> { String tel; _LoginDemoState(this.tel); TextEditingController user = new TextEditingController(); TextEditingController pwd = new TextEditingController(); @override void initState() { super.initState(); setState(() { user.text = tel; }); } } 复制代码
这里通过 setState
触发 Widget
重新构建刷新,将传递来的值设置给目标 TextField
。
- 回传参数
首先是在关闭时,加入参数 Navigator.of(context).pop('0000000');
接收时,静态和动态方式的参数回传都是通过 then
方法来完成的,这里就以动态方式为例
RaisedButton( child: Text('Login'), onPressed: () { Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context) { return LoginDemo(tel: '18700000000'); })).then((onValue) { buildDialog(context, onValue); }); }, ) 复制代码
void buildDialog(BuildContext context, String text) { showDialog( context: context, builder: (BuildContext content) { return AlertDialog( title: Text("提示"), content: Text(text), actions: <Widget>[ GestureDetector( child: Container( child: Text('关闭'), ), onTap: () { Navigator.of(context).pop(); }, ), ], ); }, ); } 复制代码
网络请求
flutter
内置 HttpClient
可以用来做网络请求,但是官方建议使用 dio
官方原话: HttpClient
本身功能较弱,很多常用功能都不支持。我们建议您使用 dio 来发起网络请求,它是一个强大易用的dart http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载
我们就从善如流,直接使用 dio
来实现网络请求
在 pubspec.yaml
文件中添加依赖 dio: ^2.1.4
void getData() { Dio dio = new Dio(); dio.request( //使用自己的接口 'https://***/module/index.php?ctl=user&act=expertList', data: {"p", "1"}, ).then((onValue) { print(onValue); setState(() { jsonString = onValue; }); }); } 复制代码
关于 dio
的更多用法,请参考 dio 官方文档
将请求返回的数据展示到 Text
上
Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('NetDemo'), actions: <Widget>[ RaisedButton( child: Text('发起请求'), onPressed: () { getData(); }, ), ], ), body: Container( child: Text('${jsonString}'), ), ); } 复制代码
JSON 序列化
上一步中,我们拿到了网络请求返回的 json
,怎么把它转换为对象呢?这就涉及到了序列化
- 1.
flutter
内置的json
,老版本中为JSON
首先,添加导入 import 'dart:convert';
void getData() { Dio dio = new Dio(); dio.request( 'https://***/module/index.php?ctl=user&act=expertList', data: {"p", "1"}, ).then((onValue) { print(onValue); //dynamic 代表动态数据类型 即可以是数字、字符串等任意类型 Map<String, dynamic> list = json.decode(onValue.toString()); setState(() { data = list['data']; }); }); } 复制代码
使用数据
Widget _listView() { return ListView.builder( itemBuilder: (context, index) { return MoveItem(data[index]); }, itemCount: data.length, ); } class MoveItem extends StatelessWidget { var model; MoveItem(this.model); @override Widget build(BuildContext context) { return Container( child: Image.network( 'http://chuangfen.oss-cn-hangzhou.aliyuncs.com' + model['head_image'], ), ); } 复制代码
虽然说问题解决了,但是这种方式的弊端很明显, 我们直到运行时才知道值的类型,这样会失去了大部分静态类型语言特性:类型安全、自动补全和最重要的编译时异常。这样一来,我们的代码可能会变得非常容易出错。
- 2.手动序列化
只需要添加 BaseModel
,并传入泛型,在其中添加 json
转对象的方法即可。
添加 BaseModel
import 'dart:convert'; class BaseModel<T> { int status; String msg; T data; BaseModel(this.status, this.msg, this.data); BaseModel.fromJson(String jsonString) { Map<String, dynamic> data = json.decode(jsonString); BaseModel(data['status'], data['msg'], data['data']); } Map<String, dynamic> toJson() => { 'status': status, 'msg': msg, 'data': data, }; } 复制代码
添加 ExpertModel
,
class ExpertModel { String nick_name; String head_image; String id; String signature; } 复制代码
这时,就可以这样使用
void getData() { Dio dio = new Dio(); dio.request( 'https://www.yfbr2018.com/module/index.php?ctl=user&act=expertList', data: {"p", "1"}, ).then((onValue) { BaseModel<List<ExpertModel>> baseModel = BaseModel<List<ExpertModel>>.fromJson(onValue.toString()); setState(() { jsonString = onValue; data = baseModel.data; }); }); } class MoveItem extends StatelessWidget { ExpertModel model; MoveItem(this.model); @override Widget build(BuildContext context) { return Container( child: Image.network( 'http://chuangfen.oss-cn-hangzhou.aliyuncs.com' + model.head_image, ), ); } 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Flutter 完整开发实战详解(十六、详解自定义布局实战)
- 实战·使用taro+云开发快速开发小程序
- 实战:小程序云开发之云函数开发
- postcss 开发实战
- Angular4 实战开发
- Python爬虫开发与项目实战
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JSP & Servlet学习笔记
【台湾】林信良 / 清华大学出版社 / 2012-5 / 58.00元
本书是作者多年来教学实践经验的总结,汇集了教学过程中学生在学习JSP & Servlet时遇到的概念、操作、应用或认证考试等问题及解决方案。 本书针对Servlet 3.0的新功能全面改版,无论是章节架构与范例程序代码,都做了全面更新。书中详细介绍了Servlet/ JSP与Web容器之间的关系,必要时从Tomcat源代码分析,了解Servlet/ JSP如何与容器互动。本书还涵盖了文本处理......一起来看看 《JSP & Servlet学习笔记》 这本书的介绍吧!