Flutter GetX 实战<小米商城>

安装get_cli

flutter pub global activate get_cli

临时: flutter pub global activate -s git https://github.com/jonataslaw/get_cli

win: 安装路径添加进path环境变量

集成

创建完项目执行get init

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
E:\CoreCode\GS\XDS\xmshop>get init
? Which architecture do you want to use? (Use arrow keys)
> GetX Pattern (by Kauê)
CLEAN (by Arktekko)
? 你的 lib 文件夹不是空的。你确定要覆盖你的应用吗?
警告:操作不可逆 (Use arrow keys)
> 是的!

'Package: get 已安装!
✓ 文件: main.dart 创建成功,路径: lib\\main.dart
✓ 文件: home_controller.dart 创建成功,路径: lib\app\modules\home\\controllers\\home_controller.dart
✓ 文件: home_view.dart 创建成功,路径: lib\app\modules\home\\views\\home_view.dart
✓ 文件: home_binding.dart 创建成功,路径: lib\app\modules\home\\bindings\\home_binding.dart
✓ 文件: app_routes.dart 创建成功,路径: lib\\app\\routes\\app_routes.dart
✓ 文件: app_pages.dart 创建成功,路径: lib\\app\\routes\\app_pages.dart
✓ home route 创建成功.
✓ Home page 创建成功.
✓ GetX 结构生成成功。

get命令创建页面

1
2
3
4
5
6
7
get create page:tabs
get create page:home
get create page:category
get create page:service
get create page:cart
get create page:user
get create page:serach

路由设置

  1. 优化页面路由 只留tabs

  2. 在tabs 的bindings里加载其他页面

    tabs_binding.dart

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    import 'package:get/get.dart';

    import '../controllers/tabs_controller.dart';
    import '../../home/controllers/home_controller.dart';
    import '../../category/controllers/category_controller.dart';
    import '../../give/controllers/give_controller.dart';
    import '../../cart/controllers/cart_controller.dart';
    import '../../user/controllers/user_controller.dart';

    class TabsBinding extends Bindings {
    @override
    void dependencies() {
    Get.lazyPut<TabsController>(
    () => TabsController(),
    );
    Get.lazyPut<HomeController>(
    () => HomeController(),
    );
    Get.lazyPut<CategoryController>(
    () => CategoryController(),
    );
    Get.lazyPut<GiveController>(
    () => GiveController(),
    );
    Get.lazyPut<CartController>(
    () => CartController(),
    );
    Get.lazyPut<UserController>(
    () => UserController(),
    );
    }
    }

配置tab切换

bottomNavigationBar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import 'package:flutter/material.dart';

import 'package:get/get.dart';

import '../controllers/tabs_controller.dart';

class TabsView extends GetView<TabsController> {
const TabsView({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Obx(() => Scaffold(
appBar: AppBar(
title: const Text('TabsView'),
centerTitle: true,
),
body: Text("tab"),
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red,
currentIndex: controller.currentIndex.value,
type: BottomNavigationBarType.fixed,
onTap: (index) {
controller.setCurrentIndex(index);
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon: Icon(Icons.room_service),
label: "服务",
),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart),
label: "购物车",
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: "我的",
)
],
),
));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import 'package:get/get.dart';

class TabsController extends GetxController {
RxInt currentIndex = 0.obs;

@override
void onInit() {
super.onInit();
}

@override
void onClose() {
super.onClose();
}

void setCurrentIndex(index) {
currentIndex.value = index;
update();
}
}

切换页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import 'package:flutter/material.dart';

import 'package:get/get.dart';

import '../controllers/tabs_controller.dart';

class TabsView extends GetView<TabsController> {
const TabsView({super.key});

@override
Widget build(BuildContext context) {
return Obx(() => Scaffold(
// 简单切换页面
// body: controller.pages[controller.currentIndex.value],
// 可左右滑动切换
body: PageView(
controller: controller.pageController,
children: controller.pages,
onPageChanged: (index) {
controller.setCurrentIndex(index);
},
),
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red,
currentIndex: controller.currentIndex.value,
type: BottomNavigationBarType.fixed,
onTap: (index) {
controller.setCurrentIndex(index);
controller.pageController.jumpToPage(index);
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon: Icon(Icons.room_service),
label: "服务",
),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart),
label: "购物车",
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: "我的",
)
],
),
));
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../cart/views/cart_view.dart';
import '../../category/views/category_view.dart';
import '../../give/views/give_view.dart';
import '../../home/views/home_view.dart';
import '../../user/views/user_view.dart';

class TabsController extends GetxController {
// 当前选中tab的索引
RxInt currentIndex = 0.obs;

// 页面列表
final List<Widget> pages = const [
HomeView(),
CategoryView(),
GiveView(),
UserView(),
CartView()
];

PageController pageController = PageController(initialPage: 0);

void setCurrentIndex(index) {
currentIndex.value = index;
update();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import 'package:flutter/material.dart';

import 'package:get/get.dart';

import '../controllers/home_controller.dart';
import '../../../services/keepAliveWrapper.dart';

class HomeView extends GetView<HomeController> {
const HomeView({super.key});

@override
Widget build(BuildContext context) {
// 页面缓存
return KeepAliveWrapper(
child: Scaffold(
appBar: AppBar(
title: const Text('HomeView'),
centerTitle: true,
),
body: ListView(
children: const [
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('2222'),
),
ListTile(
title: Text('567567567566666666666666666666'),
),
ListTile(
title: Text('567567567'),
),
ListTile(
title: Text('5675675667567'),
),
ListTile(
title: Text('111111111111'),
),
ListTile(
title: Text('111111111111'),
),
],
)));
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import 'package:flutter/material.dart';

class KeepAliveWrapper extends StatefulWidget {
const KeepAliveWrapper(
{super.key, @required this.child, this.keepAlive = true});

final Widget? child;
final bool keepAlive;

@override
State<KeepAliveWrapper> createState() => _KeepAliveWrapperState();
}

class _KeepAliveWrapperState extends State<KeepAliveWrapper>
with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
return widget.child!;
}

@override
bool get wantKeepAlive => widget.keepAlive;
}

不同终端屏幕适配

https://pub.dev/packages/flutter_screenutil

https://github.com/OpenFlutter/flutter_screenutil/blob/master/README_CN.md

pubspec.yaml

1
2
3
4
5
dependencies:
flutter:
sdk: flutter
# add flutter_screenutil
flutter_screenutil: ^5.9.3

使用的地方引入

1
import 'package:flutter_screenutil/flutter_screenutil.dart';
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//填入设计稿中设备的屏幕尺寸,单位dp
return ScreenUtilInit(
designSize: const Size(360, 690),
minTextAdapt: true,
splitScreenMode: true,
builder: (context , child) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'First Method',
// You can use the library anywhere in the app even in theme
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: Typography.englishLike2018.apply(fontSizeFactor: 1.sp),
),
home: child,
);
},
child: const HomePage(title: 'First Method'),
);
}
}

封装screenutil

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import 'package:flutter_screenutil/flutter_screenutil.dart';

/// 屏幕适配
class ScreenAdapter {
/// 获取对象的高度属性
static height(num v) {
return v.h;
}

/// 获取对象的宽度属性
static width(num v) {
return v.w;
}

/// 获取对象的字体大小属性
static fontSize(num v) {
return v.sp;
}

/// 获取屏幕宽度
static getScreenWidth() {
// return ScreenUtil().screenWidth;
return 1.sw;
}

/// 获取屏幕高度
static getScreenHeight() {
// return ScreenUtil().screenHeight;
return 1.sh;
}
}

透明状态栏

1
2
3
4
// 配置透明的状态栏
SystemUiOverlayStyle systemUiOverlayStyle =
const SystemUiOverlayStyle(statusBarColor: Colors.transparent);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);

透明顶部导航 & 上下滑动切换动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// home_view.dart
import 'package:flutter/material.dart';

import 'package:get/get.dart';
import 'package:xmshop/app/services/hyIcon.dart';
import 'package:xmshop/app/services/screenAdapter.dart';

import '../controllers/home_controller.dart';
import '../../../services/keepAliveWrapper.dart';

class HomeView extends GetView<HomeController> {
const HomeView({super.key});

@override
Widget build(BuildContext context) {
// 页面缓存
return KeepAliveWrapper(
child: Scaffold(
body: Stack(children: [
ListView.builder(
controller: controller.scrollController, // 绑定控制器
itemCount: 20,
itemBuilder: (context, index) {
if (index == 0) {
return SizedBox(
width: ScreenAdapter.width(1080),
height: ScreenAdapter.height(682),
child: Image.network(
"https://www.itying.com/images/focus/focus02.png",
fit: BoxFit.cover,
),
);
}
return ListTile(title: Text('第$index个元素'));
}),
Positioned(
top: 0,
left: 0,
right: 0,
child: Obx(() => AppBar(
leading: controller.flag.value
? const Text("")
: const Icon(
HyIcon.xiaomi,
color: Colors.white,
),
// leading 宽度
leadingWidth:
controller.flag.value ? 10 : ScreenAdapter.width(140),
// 动画容器
title: AnimatedContainer(
// 改变宽度
width: controller.flag.value
? ScreenAdapter.width(800)
: ScreenAdapter.width(620),
height: ScreenAdapter.height(96),
decoration: BoxDecoration(
color: const Color.fromARGB(200, 241, 236, 225),
borderRadius:
BorderRadius.circular(ScreenAdapter.width(50))),
duration: const Duration(milliseconds: 300),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.fromLTRB(ScreenAdapter.width(34), 0,
ScreenAdapter.width(10), 0),
child: Icon(
Icons.search,
size: ScreenAdapter.fontSize(40),
),
),
Text(
"手机",
style: TextStyle(
fontSize: ScreenAdapter.fontSize(32),
color: Colors.black54),
)
],
),
),
centerTitle: true,
backgroundColor:
controller.flag.value ? Colors.white : Colors.transparent,
elevation: 0,
actions: [
IconButton(
onPressed: () {
Get.toNamed('/cart');
},
icon: Icon(
Icons.qr_code,
color: controller.flag.value
? Colors.black87
: Colors.white,
)),
IconButton(
onPressed: () {
Get.toNamed('/cart');
},
icon: Icon(
Icons.message,
color: controller.flag.value
? Colors.black87
: Colors.white,
))
],
)))
])));
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// home_controller.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class HomeController extends GetxController {
// 滚动条控制器
final ScrollController scrollController = ScrollController();

// 开关
final RxBool flag = false.obs;

@override
void onInit() {
super.onInit();
// 监听滚动条滚动
scrollController.addListener(() {
// 下拉高度大于10时,显示返回顶部按钮
final pixels = scrollController.position.pixels;
// 根据滚动位置更新 flag 值
if (pixels >= 10 && !flag.value) {
flag.value = true;
update(); // 显示返回顶部按钮
} else if (pixels < 10 && flag.value) {
flag.value = false;
update(); // 隐藏返回顶部按钮
}
});
}

@override
void onReady() {
super.onReady();
}

@override
void onClose() {
super.onClose();
}
}

轮播图

swiper 插件

https://pub.dev/packages/flutter_swiper_view

https://github.com/feicien/flutter_swiper_view/blob/master/README-ZH.md

1
2
dependencies: 
flutter_swiper_view: ^1.1.8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import 'package:flutter/material.dart';

import 'package:flutter_swiper_view/flutter_swiper_view.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);

final String title;

@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Swiper(
itemBuilder: (context, index){
return Image.network("https://via.placeholder.com/350x150",fit: BoxFit.fill,);
},
itemCount: 3,
pagination: const SwiperPagination(),
control: const SwiperControl(),
),
);
}
}

Dio 网络请求

https://pub.dev/packages/dio

1
2
dependencies: 
dio: ^5.5.0+1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/// 内容区域
Widget _homePage() {
return Positioned(
top: -40,
left: 0,
right: 0,
bottom: 0,
// https://www.itying.com/images/focus/focus02.png
child: ListView(
controller: controller.scrollController,
children: [
SizedBox(
width: ScreenAdapter.getScreenWidth(),
height: ScreenAdapter.height(682),
child: Obx(() => Swiper(
itemBuilder: (context, index) {
String picUrl =
"https://miapp.itying.com/${controller.swiperList[index]['pic']}";
return Image.network(
picUrl.replaceAll("\\", "/"),
fit: BoxFit.fill,
);
},
itemCount: controller.swiperList.length,

pagination:
const SwiperPagination(builder: SwiperPagination.rect),
// 自动轮播
autoplay: true,
// 循环轮播
loop: true,
// 动画切换时间
duration: 2000,
)),
)
],
));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// controller
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:dio/dio.dart';

class HomeController extends GetxController {
// 滚动条控制器
final ScrollController scrollController = ScrollController();

// 浮动导航开关
final RxBool flag = false.obs;

// https://miapp.itying.com/api/focus
RxList swiperList = [].obs;

@override
void onInit() {
super.onInit();
// 监听滚动条滚动
scrollControllerListener();
// 获取焦点数据
getFocusData();
}

/// 监听滚动条滚动
scrollControllerListener() {
scrollController.addListener(() {
// 下拉高度大于10时,显示返回顶部按钮
final pixels = scrollController.position.pixels;
// 根据滚动位置更新 flag 值
if (pixels >= 10 && !flag.value) {
flag.value = true;
update(); // 显示返回顶部按钮
} else if (pixels < 10 && flag.value) {
flag.value = false;
update(); // 隐藏返回顶部按钮
}
});
}

/// 获取焦点数据
getFocusData() async {
var response = await Dio().get("https://miapp.itying.com/api/focus");
swiperList.value = response.data["result"];
update();
}
}

模型类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/// 焦点数据模型
class FocusModel {
String? sId;
String? title;
String? status;
String? pic;
String? url;

FocusModel({this.sId, this.title, this.status, this.pic, this.url});

FocusModel.fromJson(Map<String, dynamic> json) {
sId = json['_id'];
title = json['title'];
status = json['status'];
pic = json['pic'];
url = json['url'];
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['_id'] = sId;
data['title'] = title;
data['status'] = status;
data['pic'] = pic;
data['url'] = url;
return data;
}
}

在线网站生成

https://autocode.icu/jsontodart

get_cli 生成

1
get generate model on models from "https://miapp.itying.com/api/focus"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class Focus {
List<Result>? result;

Focus({this.result});

Focus.fromJson(Map<String, dynamic> json) {
if (json['result'] != null) {
result = <Result>[];
json['result'].forEach((v) {
result?.add(Result.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (result != null) {
data['result'] = result?.map((v) => v.toJson()).toList();
}
return data;
}
}

class Result {
String? sId;
String? title;
String? status;
String? pic;
String? url;
int? position;

Result(
{this.sId, this.title, this.status, this.pic, this.url, this.position});

Result.fromJson(Map<String, dynamic> json) {
sId = json['_id'];
title = json['title'];
status = json['status'];
pic = json['pic'];
url = json['url'];
position = json['position'];
}

Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['_id'] = sId;
data['title'] = title;
data['status'] = status;
data['pic'] = pic;
data['url'] = url;
data['position'] = position;
return data;
}
}

使用第三方库生成

https://doc.flutterchina.club/json/

使用

1
2
3
4
5
6
7
8
9
10
/// 获取焦点数据
getFocusData() async {
var response = await Dio().get("https://miapp.itying.com/api/focus");
print(response.data["result"]);
FocusModel focusModel = FocusModel.fromJson(response.data);
swiperList.value = focusModel.result!;
update();
}

String picUrl = "https://miapp.itying.com/${controller.swiperList[index].pic}";

轮播分类数据渲染

1
2
3
4
5
6
# 配置本地资源图片
flutter:
assets:
- assets/images/xiaomiBanner.png
- assets/images/2.0x/xiaomiBanner.png
- assets/images/3.0x/xiaomiBanner.png
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/// 分类
Widget _category() {
return SizedBox(
width: ScreenAdapter.getScreenWidth(),
height: ScreenAdapter.height(470),
child: Obx(() => Swiper(
itemBuilder: (context, index) {
return GridView.builder(
itemCount: 10,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
crossAxisSpacing: ScreenAdapter.width(20),
mainAxisSpacing: ScreenAdapter.height(20),
),
itemBuilder: (context, i) {
return Column(
children: [
Container(
alignment: Alignment.center,
width: ScreenAdapter.height(140),
height: ScreenAdapter.height(140),
child: Image.network(
"https://miapp.itying.com/${controller.categoryList[index * 10 + i].pic}",
fit: BoxFit.fitHeight,
),
),
Padding(
padding: EdgeInsets.fromLTRB(
0, ScreenAdapter.height(4), 0, 0),
child: Text(
"${controller.categoryList[index * 10 + i].title}",
style:
TextStyle(fontSize: ScreenAdapter.fontSize(34)),
),
)
],
);
});
},
itemCount: controller.categoryList.length ~/ 10, // 取整
// 自定义指示器
pagination: SwiperPagination(
margin: const EdgeInsets.all(0.0),
builder: SwiperCustomPagination(
builder: (BuildContext context, SwiperPluginConfig config) {
return ConstrainedBox(
constraints:
BoxConstraints.expand(height: ScreenAdapter.height(20)),
child: Row(
children: <Widget>[
Expanded(
child: Align(
alignment: Alignment.center,
child: const RectSwiperPaginationBuilder(
color: Colors.black12,
activeColor: Colors.black54)
.build(context, config),
),
)
],
));
}),
),
)),
);
}

封装Dio

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';

class HttpsClient {
static String domain = "https://miapp.itying.com/";
static Dio dio = Dio();

HttpsClient() {
BaseOptions options = BaseOptions();
options.baseUrl = domain;
// 超时时间
options.connectTimeout = const Duration(seconds: 5);
// 接收数据超时时间
options.receiveTimeout = const Duration(seconds: 5);
// 响应数据格式
options.responseType = ResponseType.json;
dio.options = options;
}

Future<dynamic> get(String url) async {
try {
var response = dio.get(url);
return response;
} catch (e) {
Fluttertoast.showToast(
msg: "请求数据异常",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
return null;
}
}

static replaceUri(pic) {
String picUrl = domain + pic;
return picUrl.replaceAll("\\", "/");
}
}


Flutter GetX 实战<小米商城>
https://jhyjhy.cn/posts/64979/
作者
jhy
发布于
2024年8月7日
许可协议