60e47f7c
liangchengyou
feat:课程选择功能
|
1
2
|
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
|
60e47f7c
liangchengyou
feat:课程选择功能
|
3
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
60e47f7c
liangchengyou
feat:课程选择功能
|
4
|
import 'package:wow_english/common/widgets/we_app_bar.dart';
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
5
6
|
import 'package:wow_english/models/course_module_entity.dart';
import 'package:wow_english/route/route.dart';
|
4b358e22
liangchengyou
feat:调整文件结构
|
7
|
|
42f15f6c
吴启风
feat:模块选择持久化&模块主题...
|
8
|
import '../../common/core/module_cache.dart';
|
37063ced
吴启风
feat:阶段选择指示器与阶段色联...
|
9
|
import '../../common/utils/click_with_music_controller.dart';
|
42f15f6c
吴启风
feat:模块选择持久化&模块主题...
|
10
|
import '../../common/utils/color_parser.dart';
|
37063ced
吴启风
feat:阶段选择指示器与阶段色联...
|
11
|
import '../../utils/audio_player_util.dart';
|
2187c85f
吴启风
feat:课程结构调整
|
12
13
|
import 'bloc/module_bloc.dart';
import 'widgets/module_item_widget.dart';
|
60e47f7c
liangchengyou
feat:课程选择功能
|
14
|
|
5b87e560
吴启风
feat:导航栏视觉优化
|
15
16
17
|
// 课程阶段(模块)列表页
class CourseModulePage extends StatelessWidget {
const CourseModulePage({super.key, this.starPageIndex});
|
60e47f7c
liangchengyou
feat:课程选择功能
|
18
19
20
|
final int? starPageIndex;
|
60e47f7c
liangchengyou
feat:课程选择功能
|
21
22
23
|
@override
Widget build(BuildContext context) {
return BlocProvider(
|
2187c85f
吴启风
feat:课程结构调整
|
24
25
26
|
create: (context) => ModuleBloc(
starPageIndex ?? 0,
PageController(initialPage: starPageIndex ?? 0, viewportFraction: 0.3),
|
842b7132
liangchengyou
feat:磨耳朵/练习页面调整
|
27
|
)..add(RequestDataEvent()),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
28
29
30
31
32
33
|
child: _LessonPageView(),
);
}
}
class _LessonPageView extends StatelessWidget {
|
f0d56772
liangchengyou
feat:更新尺寸适配
|
34
|
final double _cardHeight = 240.h;
|
60e47f7c
liangchengyou
feat:课程选择功能
|
35
|
|
60e47f7c
liangchengyou
feat:课程选择功能
|
36
37
38
39
|
final double _scale = 0.8;
@override
Widget build(BuildContext context) {
|
2187c85f
吴启风
feat:课程结构调整
|
40
41
|
return BlocListener<ModuleBloc, ModuleState>(
listener: (context, state) {},
|
60e47f7c
liangchengyou
feat:课程选择功能
|
42
|
child: Scaffold(
|
5b87e560
吴启风
feat:导航栏视觉优化
|
43
|
appBar: const WEAppBar(),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
44
45
46
47
48
|
body: _lessViewWidget(),
),
);
}
|
2187c85f
吴启风
feat:课程结构调整
|
49
50
51
|
Widget _lessViewWidget() =>
BlocBuilder<ModuleBloc, ModuleState>(builder: (context, state) {
final bloc = BlocProvider.of<ModuleBloc>(context);
|
60e47f7c
liangchengyou
feat:课程选择功能
|
52
53
54
55
56
57
58
|
return Center(
child: SafeArea(
child: Column(
children: [
SizedBox(
height: _cardHeight,
child: PageView.builder(
|
993c1a04
liangchengyou
feat:添加数据模型
|
59
|
itemCount: bloc.listData.length,
|
60e47f7c
liangchengyou
feat:课程选择功能
|
60
61
62
63
|
controller: bloc.pageController,
onPageChanged: (int index) {
bloc.add(PageViewChangeIndexEvent(index));
},
|
2187c85f
吴启风
feat:课程结构调整
|
64
|
itemBuilder: (context, index) => _itemTransCard(index)),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
65
66
67
|
),
32.verticalSpace,
SizedBox(
|
f0d56772
liangchengyou
feat:更新尺寸适配
|
68
|
height: 32.h,
|
6f617434
liangchengyou
feat:磨耳朵/视频跟读列表页接口调整
|
69
|
width: 66.w * bloc.listData.length,
|
60e47f7c
liangchengyou
feat:课程选择功能
|
70
|
child: ListView.builder(
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
71
|
itemCount: bloc.listData.length,
|
60e47f7c
liangchengyou
feat:课程选择功能
|
72
|
scrollDirection: Axis.horizontal,
|
2187c85f
吴启风
feat:课程结构调整
|
73
|
itemBuilder: (BuildContext context, int index) {
|
37063ced
吴启风
feat:阶段选择指示器与阶段色联...
|
74
|
CourseModuleEntity? model = bloc.listData[index];
|
60e47f7c
liangchengyou
feat:课程选择功能
|
75
|
return Container(
|
f0d56772
liangchengyou
feat:更新尺寸适配
|
76
77
|
height: 32.h,
width: 66.w,
|
60e47f7c
liangchengyou
feat:课程选择功能
|
78
79
80
81
82
83
|
padding: const EdgeInsets.symmetric(horizontal: 5),
child: GestureDetector(
onTap: () {
if (index == bloc.currentPageIndex) {
return;
}
|
2187c85f
吴启风
feat:课程结构调整
|
84
85
86
87
88
89
|
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:课程选择功能
|
90
91
|
},
child: Container(
|
2187c85f
吴启风
feat:课程结构调整
|
92
|
height: bloc.currentPageIndex == index ? 32 : 20,
|
60e47f7c
liangchengyou
feat:课程选择功能
|
93
|
decoration: BoxDecoration(
|
37063ced
吴启风
feat:阶段选择指示器与阶段色联...
|
94
95
96
|
// color: bloc.currentPageIndex == index
// ? Colors.red
// : Colors.white,
|
0427feeb
吴启风
feat:增加播放器对页面生命周期...
|
97
98
99
100
|
color: parseColor(model.getSafeThemeColor())
.withOpacity(bloc.currentPageIndex == index
? 1
: 0.15),
|
6f617434
liangchengyou
feat:磨耳朵/视频跟读列表页接口调整
|
101
|
borderRadius: BorderRadius.circular(5.r),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
102
103
104
105
106
107
108
|
border: Border.all(
width: 0.5,
color: Colors.black,
),
),
alignment: Alignment.center,
child: Text(
|
2187c85f
吴启风
feat:课程结构调整
|
109
|
(index + 1).toString(),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
110
|
style: TextStyle(
|
2187c85f
吴启风
feat:课程结构调整
|
111
112
113
|
color: bloc.currentPageIndex == index
? Colors.white
: Colors.black),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
114
115
116
117
118
|
),
),
),
);
}),
|
60e47f7c
liangchengyou
feat:课程选择功能
|
119
120
121
122
123
124
125
|
)
],
),
),
);
});
|
2187c85f
吴启风
feat:课程结构调整
|
126
127
128
129
130
131
132
133
134
|
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:课程选择功能
|
135
|
|
2187c85f
吴启风
feat:课程结构调整
|
136
137
138
139
140
141
142
|
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:课程选择功能
|
143
|
|
2187c85f
吴启风
feat:课程结构调整
|
144
145
146
147
148
149
150
|
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:课程选择功能
|
151
|
|
2187c85f
吴启风
feat:课程结构调整
|
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
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: () {
|
42f15f6c
吴启风
feat:模块选择持久化&模块主题...
|
168
|
ModuleCache.instance.currentModule = model;
|
37063ced
吴启风
feat:阶段选择指示器与阶段色联...
|
169
170
171
172
173
174
175
|
///todo 不同阶段音乐文件待提供
ClickWithMusicController.instance.playMusicAndPerformAction(
context,
AudioPlayerUtilType.welcomeToWow,
() => pushNamedAndRemoveUntil(
AppRouteName.courseUnit, (route) => route.isFirst,
arguments: {'courseModuleEntity': model}));
|
2187c85f
吴启风
feat:课程结构调整
|
176
177
|
},
),
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
178
|
),
|
2187c85f
吴启风
feat:课程结构调整
|
179
180
|
);
});
|
c61b3c1a
Key
feat: toast_util....
|
181
|
}
|