## 1. GetConnect
GetConnect是可以使用HTTP或WebSocks使前台与后台的通信,同时能保证数据出现错误时,不会出现App闪退
1.1 如何使用
第一步:创建模型model
class MakeupModel {
// 略了
}
第二步:创建 provider 集成自 GetConnect
const String APIADDRESS =
'https://makeup-api.herokuapp.com/api/v1/products.json/';
class HomeProvider extends GetConnect {
@override
void onInit() {
// 这个是json转model的, 可以这么写
// httpClient.defaultDecoder = (json) => MakeupModel.fromJson(json);
// 也可以这么写
httpClient.defaultDecoder = MakeupModel.fromJson;
// 创建公共接口地址
httpClient.baseUrl = APIADDRESS;
}
// 获取接口数据源
Future<Response<List<MakeupModel>>> getMakeupModel() async =>
await get('?brand=maybelline');
}
// 多个接口的话,可以在抽离出来一层,毕竟接口地址 和 请求拦截,响应拦截等都是固定的
class BaseConnect extends GetConnect {
@override
void onInit() {
// 创建公共接口地址
httpClient.baseUrl = APIADDRESS;
// 请求拦截
httpClient.addRequestModifier((request) {
request.headers["token"] = "token";
return request;
});
// 响应拦截
httpClient.addResponseModifier((request, response) {
// 处理逻辑
return response;
});
}
}
class HomeProvider extends BaseConnect {
@override
void onInit() {
// 某个接口的json-to-model
httpClient.defaultDecoder = MakeupModel.fromJson;
super.onInit();
}
Future<Response<List<MakeupModel>>> getMakeupModel() async =>
await get('?brand=maybelline');
}
第三步:创建 controller 集成自 GetxController 混入 StateMixin
/// 创建controller
class HomeController extends GetxController with StateMixin<List<MakeupModel>> {
// 获取实例
final provider = Get.find<HomeProvider>();
@override
void onInit() {
// 调用
fetchList();
super.onInit();
}
// 处理接口返回的数据
Future<void> fetchList() async {
// 获取数据
final Response res = await provider.getMakeupModel();
// 判断,如果有错误
if (res.hasError) {
// 改变数据,传入错误状态,在ui中会处理这些错误
change(null, status: RxStatus.error(res.statusText));
} else {
// 否则,存储数据,改变状态为成功
change(res.body, status: RxStatus.success());
}
}
}
第四步:创建 binding 实现 Bindings类
class HomeBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<HomeController>(() => HomeController());
Get.lazyPut<HomeProvider>(() => HomeProvider());
}
}
第五步: 连接UI渲染数据
渲染时,需要使用 controller.obx()
拿到接口中的数据
传入参数 | 说明 | |
---|---|---|
(state) => Widget | 传入函数,参数是接口返回的数据,返回值是要渲染的组件 | |
onEmpty | 传入一个组件,在数据为空时展示 | |
onLoading | 传入一个组件,在数据加载时显示的loading | |
onError | (String) => Widget,发生错误时渲染 |
class Home extends GetView<HomeController> {
const Home({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Make up'),
),
body: controller.obx(
(state) => ListView.separated(
itemCount: state.length,
itemBuilder: (context, index) {
final MakeupModel makeUp = state[index];
return ListTile(
onTap: () => null,
title: Text(makeUp.name),
trailing: Text("\$${makeUp.price}"),
leading: MakeUpImage(makeUp: makeUp),
);
},
),
onError: (err) {
return Text("$err");
},
// 自定义loading和文字,不传的话,默认只有一个loading,没有文字
onLoading: Container(
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 10),
Text(
"疯狂加载中...",
style: TextStyle(color: Colors.blue, fontSize: 16),
),
],
),
),
),
);
}
}