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