60e47f7c
liangchengyou
feat:课程选择功能
|
1
2
|
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
|
60e47f7c
liangchengyou
feat:课程选择功能
|
3
4
5
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:wow_english/common/extension/string_extension.dart';
import 'package:wow_english/common/widgets/we_app_bar.dart';
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
6
7
|
import 'package:wow_english/models/course_module_entity.dart';
import 'package:wow_english/route/route.dart';
|
4b358e22
liangchengyou
feat:调整文件结构
|
8
|
|
2187c85f
吴启风
feat:课程结构调整
|
9
10
|
import 'bloc/module_bloc.dart';
import 'widgets/module_item_widget.dart';
|
60e47f7c
liangchengyou
feat:课程选择功能
|
11
|
|
2187c85f
吴启风
feat:课程结构调整
|
12
13
14
|
// 阶段(模块)列表页
class ModulePage extends StatelessWidget {
const ModulePage({super.key, this.starPageIndex});
|
60e47f7c
liangchengyou
feat:课程选择功能
|
15
16
17
|
final int? starPageIndex;
|
60e47f7c
liangchengyou
feat:课程选择功能
|
18
19
20
|
@override
Widget build(BuildContext context) {
return BlocProvider(
|
2187c85f
吴启风
feat:课程结构调整
|
21
22
23
|
create: (context) => ModuleBloc(
starPageIndex ?? 0,
PageController(initialPage: starPageIndex ?? 0, viewportFraction: 0.3),
|
842b7132
liangchengyou
feat:磨耳朵/练习页面调整
|
24
|
)..add(RequestDataEvent()),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
25
26
27
28
29
30
|
child: _LessonPageView(),
);
}
}
class _LessonPageView extends StatelessWidget {
|
f0d56772
liangchengyou
feat:更新尺寸适配
|
31
|
final double _cardHeight = 240.h;
|
60e47f7c
liangchengyou
feat:课程选择功能
|
32
|
|
60e47f7c
liangchengyou
feat:课程选择功能
|
33
34
35
36
|
final double _scale = 0.8;
@override
Widget build(BuildContext context) {
|
2187c85f
吴启风
feat:课程结构调整
|
37
38
|
return BlocListener<ModuleBloc, ModuleState>(
listener: (context, state) {},
|
60e47f7c
liangchengyou
feat:课程选择功能
|
39
40
|
child: Scaffold(
appBar: WEAppBar(
|
d35a4e87
liangchengyou
feat:磨耳朵功能UI
|
41
|
leading: IconButton(
|
2187c85f
吴启风
feat:课程结构调整
|
42
43
|
onPressed: () {
popPage();
|
d35a4e87
liangchengyou
feat:磨耳朵功能UI
|
44
45
46
47
48
|
},
icon: Image.asset(
'back'.assetPng,
height: 43,
width: 43,
|
2187c85f
吴启风
feat:课程结构调整
|
49
|
)),
|
6f617434
liangchengyou
feat:磨耳朵/视频跟读列表页接口调整
|
50
51
52
53
54
|
// actions: <Widget>[
// IconButton(
// icon: Image.asset('shop'.assetPng),
// color: Colors.white,
// onPressed: () {
|
c61b3c1a
Key
feat: toast_util....
|
55
|
// showToast('购买');
|
6f617434
liangchengyou
feat:磨耳朵/视频跟读列表页接口调整
|
56
57
58
|
// },
// )
// ],
|
60e47f7c
liangchengyou
feat:课程选择功能
|
59
60
61
62
63
64
|
),
body: _lessViewWidget(),
),
);
}
|
2187c85f
吴启风
feat:课程结构调整
|
65
66
67
|
Widget _lessViewWidget() =>
BlocBuilder<ModuleBloc, ModuleState>(builder: (context, state) {
final bloc = BlocProvider.of<ModuleBloc>(context);
|
60e47f7c
liangchengyou
feat:课程选择功能
|
68
69
70
71
72
73
74
|
return Center(
child: SafeArea(
child: Column(
children: [
SizedBox(
height: _cardHeight,
child: PageView.builder(
|
993c1a04
liangchengyou
feat:添加数据模型
|
75
|
itemCount: bloc.listData.length,
|
60e47f7c
liangchengyou
feat:课程选择功能
|
76
77
78
79
|
controller: bloc.pageController,
onPageChanged: (int index) {
bloc.add(PageViewChangeIndexEvent(index));
},
|
2187c85f
吴启风
feat:课程结构调整
|
80
|
itemBuilder: (context, index) => _itemTransCard(index)),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
81
82
83
|
),
32.verticalSpace,
SizedBox(
|
f0d56772
liangchengyou
feat:更新尺寸适配
|
84
|
height: 32.h,
|
6f617434
liangchengyou
feat:磨耳朵/视频跟读列表页接口调整
|
85
|
width: 66.w * bloc.listData.length,
|
60e47f7c
liangchengyou
feat:课程选择功能
|
86
|
child: ListView.builder(
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
87
|
itemCount: bloc.listData.length,
|
60e47f7c
liangchengyou
feat:课程选择功能
|
88
|
scrollDirection: Axis.horizontal,
|
2187c85f
吴启风
feat:课程结构调整
|
89
|
itemBuilder: (BuildContext context, int index) {
|
60e47f7c
liangchengyou
feat:课程选择功能
|
90
|
return Container(
|
f0d56772
liangchengyou
feat:更新尺寸适配
|
91
92
|
height: 32.h,
width: 66.w,
|
60e47f7c
liangchengyou
feat:课程选择功能
|
93
94
95
96
97
98
|
padding: const EdgeInsets.symmetric(horizontal: 5),
child: GestureDetector(
onTap: () {
if (index == bloc.currentPageIndex) {
return;
}
|
2187c85f
吴启风
feat:课程结构调整
|
99
100
101
102
103
104
|
int mill = (index - bloc.currentPageIndex) > 0
? 100 * (index - bloc.currentPageIndex)
: 100 * (bloc.currentPageIndex - index);
bloc.pageController.animateToPage(index,
duration: Duration(milliseconds: mill),
curve: Curves.ease);
|
60e47f7c
liangchengyou
feat:课程选择功能
|
105
106
|
},
child: Container(
|
2187c85f
吴启风
feat:课程结构调整
|
107
|
height: bloc.currentPageIndex == index ? 32 : 20,
|
60e47f7c
liangchengyou
feat:课程选择功能
|
108
|
decoration: BoxDecoration(
|
2187c85f
吴启风
feat:课程结构调整
|
109
110
111
|
color: bloc.currentPageIndex == index
? Colors.red
: Colors.white,
|
6f617434
liangchengyou
feat:磨耳朵/视频跟读列表页接口调整
|
112
|
borderRadius: BorderRadius.circular(5.r),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
113
114
115
116
117
118
119
|
border: Border.all(
width: 0.5,
color: Colors.black,
),
),
alignment: Alignment.center,
child: Text(
|
2187c85f
吴启风
feat:课程结构调整
|
120
|
(index + 1).toString(),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
121
|
style: TextStyle(
|
2187c85f
吴启风
feat:课程结构调整
|
122
123
124
|
color: bloc.currentPageIndex == index
? Colors.white
: Colors.black),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
125
126
127
128
129
|
),
),
),
);
}),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
130
131
132
133
134
135
136
|
)
],
),
),
);
});
|
2187c85f
吴启风
feat:课程结构调整
|
137
138
139
140
141
142
143
144
145
|
Widget _itemTransCard(int index) =>
BlocBuilder<ModuleBloc, ModuleState>(builder: (context, state) {
final bloc = BlocProvider.of<ModuleBloc>(context);
Matrix4 matrix4 = Matrix4.identity();
if (index == bloc.currentPageIndex.floor()) {
//当前的item
double currScale =
(1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble();
var currTrans = _cardHeight * (1 - currScale) / 2;
|
60e47f7c
liangchengyou
feat:课程选择功能
|
146
|
|
2187c85f
吴启风
feat:课程结构调整
|
147
148
149
150
151
152
153
|
matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)
..setTranslationRaw(0.0, currTrans, 0.0);
} else if (index == bloc.currentPageIndex.floor() + 1) {
//右边的item
var currScale =
_scale + (bloc.currentPageIndex - index + 1) * (1 - _scale);
var currTrans = _cardHeight * (1 - currScale) / 2;
|
60e47f7c
liangchengyou
feat:课程选择功能
|
154
|
|
2187c85f
吴启风
feat:课程结构调整
|
155
156
157
158
159
160
161
|
matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)
..setTranslationRaw(0.0, currTrans, 0.0);
} else if (index == bloc.currentPageIndex - 1) {
//左边
var currScale =
(1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble();
var currTrans = _cardHeight * (1 - currScale) / 2;
|
60e47f7c
liangchengyou
feat:课程选择功能
|
162
|
|
2187c85f
吴启风
feat:课程结构调整
|
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)
..setTranslationRaw(0.0, currTrans, 0.0);
} else {
//其他,不在屏幕显示的item
matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0)
..setTranslationRaw(0.0, _cardHeight * (1 - _scale) / 2, 0.0);
}
CourseModuleEntity? model = bloc.listData[index];
return Transform(
transform: matrix4,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: ModuleItemWidget(
model: model,
isSelected: bloc.currentPageIndex == index,
onClickEvent: () {
pushNamedAndRemoveUntil(
AppRouteName.courseUnit, (route) => route.isFirst,
arguments: {'courseModuleEntity': model});
},
),
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
184
|
),
|
2187c85f
吴启风
feat:课程结构调整
|
185
186
|
);
});
|
c61b3c1a
Key
feat: toast_util....
|
187
|
}
|