内容简介:首先要在然后进行跳转
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爬虫开发与项目实战
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Pro Django
Marty Alchin / Apress / 2008-11-24 / USD 49.99
Django is the leading Python web application development framework. Learn how to leverage the Django web framework to its full potential in this advanced tutorial and reference. Endorsed by Django, Pr......一起来看看 《Pro Django》 这本书的介绍吧!