Flutter flatter如何使用provider进行api调用,或者更好地使用未来的构建器
我需要知道如何通过良好的实践调用api。现在我只是在函数中调用我的api,通过设置state更改应用程序页面的状态并显示我的数据 我需要知道的是,我使用的是正确的还是错误的做法?我能为良好的实践做些什么。我正在考虑使用FutureBuilder,但在一些地方,我读到使用provider进行api调用是可以的 我现在的代码Flutter flatter如何使用provider进行api调用,或者更好地使用未来的构建器,flutter,dart,Flutter,Dart,我需要知道如何通过良好的实践调用api。现在我只是在函数中调用我的api,通过设置state更改应用程序页面的状态并显示我的数据 我需要知道的是,我使用的是正确的还是错误的做法?我能为良好的实践做些什么。我正在考虑使用FutureBuilder,但在一些地方,我读到使用provider进行api调用是可以的 我现在的代码 class _ProfileScreenState extends State<ProfileScreen> { @override void initSt
class _ProfileScreenState extends State<ProfileScreen> {
@override
void initState() {
super.initState();
getImi();
}
bool loading = true;
String mobile;
String email;
String address;
String numberplate;
String carName;
String engineNumber;
String chassisNumber;
String namE;
String odometer;
getImi() async {
final storage = new FlutterSecureStorage();
String imi = await storage.read(key: "imei");
print('showimi');
print(imi);
var map = new Map<String, dynamic>();
var url =
'http://myapi.php?imei=${imi}';
print(url);
http.Response res = await http.get(
url,
headers: <String, String>{'token': 'dsadasda'},
);
var data = json.decode(res.body.toString());
print(data);
print(data[0]['mobile']);
if (data[0]['mobile'].toString().length >= 1) {
loading = false;
setState(() {
mobile = data[0]['mobile'].toString();
email = data[0]['contact_email'].toString();
address = data[0]['address'].toString();
numberplate = data[0]['number plate'].toString();
carName = data[0]['car name'].toString();
engineNumber = data[0]['vehicle engine'].toString();
chassisNumber = data[0]['vehicle chassis'].toString();
namE = data[0]['contact name'].toString();
odometer = data[0]['odometer'].toString();
});
}
}
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
var data;
return Container(
color: Colors.white,
child: Column(
children: [
Container(
color: Colors.grey[400],
width: double.infinity,
height: height * 0.3,
child: Center(
child: Text(
loading == false ? namE : '....',
style: TextStyle(
fontSize: 25,
color: Colors.white,
fontFamily: 'UbuntuMedium',
),
)),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
children: [
Image.asset(
'images/call-icon@2x.png',
height: height * 0.045,
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
loading == false ? mobile : '....',
style: TextStyle(
fontSize: 17,
fontFamily: 'UbuntuRegular',
),
),
SizedBox(
height: height * 0.007,
),
Text(
'Mobile',
style: TextStyle(
fontSize: 17,
fontFamily: 'UbuntuRegular',
color: Colors.grey),
),
],
),
)
],
),
),
Container(
height: height * 0.001,
color: Colors.grey,
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
children: [
Image.asset(
'images/contact-us-icon-sc@2x.png',
height: height * 0.045,
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
loading == false ? email : '....',
style: TextStyle(
fontSize: 17,
fontFamily: 'UbuntuRegular',
),
),
SizedBox(
height: height * 0.007,
),
Text(
'Personal',
style: TextStyle(
fontSize: 17,
fontFamily: 'UbuntuRegular',
color: Colors.grey),
),
],
),
)
],
),
),
],
),
);
}
}
class\u ProfileScreenState扩展状态{
@凌驾
void initState(){
super.initState();
getImi();
}
布尔加载=真;
字符串移动;
字符串电子邮件;
字符串地址;
字符串数字板;
丝状肉桂;
字符串引擎;
字符串编号;
字符串名;
弦式里程表;
getImi()异步{
最终存储=新存储();
字符串imi=wait storage.read(键:“imei”);
印刷品(‘showimi’);
打印(imi);
var map=newmap();
变量url=
'http://myapi.php?imei=${imi}';
打印(url);
Response res=wait http.get(
网址,
标题:{'token':'dsadasda'},
);
var data=json.decode(res.body.toString());
打印(数据);
打印(数据[0]['mobile']);
如果(数据[0]['mobile'].toString().length>=1){
加载=假;
设置状态(){
mobile=data[0]['mobile'].toString();
email=data[0]['contact_email'].toString();
地址=数据[0]['address'].toString();
numberplate=数据[0]['number plate'].toString();
carName=data[0]['car name'].toString();
engineNumber=数据[0]['vehicle engine'].toString();
chassisNumber=数据[0][“车辆底盘”]。toString();
namE=数据[0]['contact namE'].toString();
里程表=数据[0]['odometer'].toString();
});
}
}
@凌驾
小部件构建(构建上下文){
double width=MediaQuery.of(context).size.width;
double height=MediaQuery.of(context).size.height;
var数据;
返回容器(
颜色:颜色,白色,
子:列(
儿童:[
容器(
颜色:颜色。灰色[400],
宽度:double.infinity,
高度:高度*0.3,
儿童:中心(
子:文本(
加载==false?名称:'..',
样式:TextStyle(
尺寸:25,
颜色:颜色,白色,
fontFamily:“UbuntuMedium”,
),
)),
),
填充物(
填充:常数边集全部(20.0),
孩子:排(
儿童:[
影像资产(
“图像/呼叫-icon@2x.png',
高度:高度*0.045,
),
填充物(
填充:仅限常量边集(左:20),
子:列(
mainAxisAlignment:mainAxisAlignment.start,
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
正文(
加载==false?移动:'..',
样式:TextStyle(
尺寸:17,
fontFamily:“UbuntuRegular”,
),
),
大小盒子(
高度:高度*0.007,
),
正文(
"流动",,
样式:TextStyle(
尺寸:17,
fontFamily:“UbuntuRegular”,
颜色:颜色。灰色),
),
],
),
)
],
),
),
容器(
高度:高度*0.001,
颜色:颜色。灰色,
),
填充物(
填充:常数边集全部(20.0),
孩子:排(
儿童:[
影像资产(
'图片/联系我们图标-sc@2x.png',
高度:高度*0.045,
),
填充物(
填充:仅限常量边集(左:20),
子:列(
mainAxisAlignment:mainAxisAlignment.start,
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
正文(
加载==false?电子邮件:'..'',
样式:TextStyle(
尺寸:17,
fontFamily:“UbuntuRegular”,
),
),
大小盒子(
高度:高度*0.007,
),
正文(
"私人",,
样式:TextStyle(
尺寸:17,
fontFamily:“UbuntuRegular”,
颜色:颜色。灰色),
),
],
),
)
],
),
),
],
),
);
}
}
对于小项目,设置状态是可以的
我发现使用具有某种MVVM体系结构(模型-视图-视图-模型)的提供程序包非常好而且干净
下面是一个简单的小例子,你可以从它开始
应用程序的每个视图(页面)必须具有保存视图状态的ViewModel;视图渲染从ViewModel读取状态;视图调用调用数据服务的ViewModel函数
将数据(如所有这些:data[0]['mobile'])放在类(SampleData)中有助于保持代码干净并避免错误
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MaterialApp(
home: Material(
child: ChangeNotifierProvider<DataNotifier>(
create: (_) => DataNotifier(), child: MyApp()),
)));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final dataNotifier = Provider.of<DataNotifier>(context);
if (dataNotifier.dataLoaded) return Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Text(dataNotifier.data),
Text(
dataNotifier.listData.fold("LIST: ", (previousValue, e) => "$previousValue [${e.id} ${e.name}]"),
)]);
return Text("Waiting...");
}
}
class DataNotifier with ChangeNotifier {
bool _dataLoaded;
bool get dataLoaded => _dataLoaded;
DataService _service;
String _data;
String get data => _data;
List<SampleData> _listData;
List<SampleData> get listData => _listData;
DataNotifier() {
_dataLoaded = false;
_service = DataService();
getData();
}
void getData() async {
_data = await _service.getData();
_listData = await _service.getListData();
_dataLoaded = true;
notifyListeners();
}
}
class DataService {
Future<String> getData() async {
return Future<String>.delayed(
const Duration(seconds: 5),
() => 'Data Loaded',
);
}
Future<List<SampleData>> getListData() async {
return Future<List<SampleData>>.delayed(
const Duration(seconds: 5),
() => List.generate(100, (index) => SampleData(index, "name_$index")),
);
}
}
class SampleData {
int id;
String name;
SampleData(this.id, this.name);
}
导入“包装:颤振/材料.省道”;
导入“包:provider/provider.dart”;
真空总管