這一篇,咱們說說開發中會用到的地方。php
Flutter
的頁面跳轉,主要是經過Navigator
來實現,相似原生中的路由,分爲靜態和動態2種方式。java
首先要在MaterialApp
的routes
中進行註冊git
MaterialApp(
routes: {
'base': (BuildContext context) {
return BaseDemo();
},
'login': (BuildContext context) {
return LoginDemo();
}
},
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.brown,
),
home: MainDemo(),
);
複製代碼
而後進行跳轉github
RaisedButton(
child: Text('BaseWidget'),
onPressed: () {
Navigator.pushNamed(context, 'base');
},
)
複製代碼
這種方式的缺點也比較明顯,首先須要註冊,其次是不能傳遞參數json
須要構建MaterialPageRoute
安全
RaisedButton(
child: Text('PageView'),
onPressed: () {
Navigator.push(context,
new MaterialPageRoute(builder: (BuildContext context) {
return PageViewDemo();
}));
},
)
複製代碼
主要是經過pop
方法來實現 Navigator.of(context).pop();
網絡
首先,須要在目標Widget
中定義參數app
class LoginDemo extends StatefulWidget {
@override
_LoginDemoState createState() => _LoginDemoState(tel);
final String tel;
LoginDemo({Key key, @required this.tel}) : super(key: key);
}
複製代碼
再傳遞參數less
RaisedButton(
child: Text('Login'),
onPressed: () {
Navigator.push(context,
new MaterialPageRoute(builder: (BuildContext context) {
return LoginDemo(tel: '18700000000');
}));
},
)
複製代碼
目標Widget
取值,這裏用到的是上一篇中的登陸示例,詳情能夠查看【Flutter】開發之高級Widget(三)ide
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
,怎麼把它轉換爲對象呢?這就涉及到了序列化
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'],
),
);
}
複製代碼
雖說問題解決了,可是這種方式的弊端很明顯,咱們直到運行時才知道值的類型,這樣會失去了大部分靜態類型語言特性:類型安全、自動補全和最重要的編譯時異常。這樣一來,咱們的代碼可能會變得很是容易出錯。
只須要添加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,
),
);
}
複製代碼