Commit d35a4e8794ec9bdbbbbbe6092105a53615731422

Authored by liangchengyou
1 parent 60e47f7c

feat:磨耳朵功能UI

assets/images/back_around.png 0 → 100644

17.2 KB

assets/images/blue-positive.png 0 → 100644

22.6 KB

assets/images/listen_lock.png 0 → 100644

3.79 KB

lib/app/splash_page.dart
@@ -29,7 +29,7 @@ class _TransitionViewState extends State<TransitionView> { @@ -29,7 +29,7 @@ class _TransitionViewState extends State<TransitionView> {
29 Future startTime() async { 29 Future startTime() async {
30 Timer(const Duration(seconds: 2),() { 30 Timer(const Duration(seconds: 2),() {
31 if(BasicConfigurationManager().sessionId!.isNotEmpty) { 31 if(BasicConfigurationManager().sessionId!.isNotEmpty) {
32 - Navigator.of(context).pushNamedAndRemoveUntil(AppRouteName.tab, (route) => false); 32 + Navigator.of(context).pushNamedAndRemoveUntil(AppRouteName.home, (route) => false);
33 } else { 33 } else {
34 Navigator.of(context).pushNamedAndRemoveUntil(AppRouteName.login,(route) => false); 34 Navigator.of(context).pushNamedAndRemoveUntil(AppRouteName.login,(route) => false);
35 } 35 }
lib/common/widgets/we_app_bar.dart
@@ -31,9 +31,9 @@ class WEAppBar extends StatelessWidget implements PreferredSizeWidget { @@ -31,9 +31,9 @@ class WEAppBar extends StatelessWidget implements PreferredSizeWidget {
31 child: Container( 31 child: Container(
32 alignment: Alignment.center, 32 alignment: Alignment.center,
33 child: Image.asset( 33 child: Image.asset(
34 - 'back'.assetPng,  
35 - height: 43,  
36 - width: 43, 34 + 'back_around'.assetPng,
  35 + height: 40,
  36 + width: 40,
37 ), 37 ),
38 ), 38 ),
39 ), 39 ),
lib/home/bloc/home_bloc.dart
1 -import 'dart:async';  
2 -  
3 -import 'package:bloc/bloc.dart';  
4 -import 'package:meta/meta.dart'; 1 +import 'package:flutter/cupertino.dart';
  2 +import 'package:flutter_bloc/flutter_bloc.dart';
5 3
6 part 'home_event.dart'; 4 part 'home_event.dart';
7 part 'home_state.dart'; 5 part 'home_state.dart';
8 6
9 class HomeBloc extends Bloc<HomeEvent, HomeState> { 7 class HomeBloc extends Bloc<HomeEvent, HomeState> {
10 - HomeBloc() : super(HomeInitial()) { 8 + final PageController pageController;
  9 + HomeBloc(this.pageController) : super(HomeInitial()) {
11 on<HomeEvent>((event, emit) { 10 on<HomeEvent>((event, emit) {
12 // TODO: implement event handler 11 // TODO: implement event handler
13 }); 12 });
lib/home/home_page.dart
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 2 import 'package:flutter_bloc/flutter_bloc.dart';
  3 +import 'package:flutter_easyloading/flutter_easyloading.dart';
  4 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  5 +import 'package:wow_english/common/extension/string_extension.dart';
3 import 'package:wow_english/home/bloc/home_bloc.dart'; 6 import 'package:wow_english/home/bloc/home_bloc.dart';
  7 +import 'package:wow_english/home/widgets/home_lesson_item_widget.dart';
4 import 'package:wow_english/home/widgets/home_tab_header_widget.dart'; 8 import 'package:wow_english/home/widgets/home_tab_header_widget.dart';
5 import 'package:wow_english/route/route.dart'; 9 import 'package:wow_english/route/route.dart';
6 10
@@ -10,7 +14,9 @@ class HomePage extends StatelessWidget { @@ -10,7 +14,9 @@ class HomePage extends StatelessWidget {
10 @override 14 @override
11 Widget build(BuildContext context) { 15 Widget build(BuildContext context) {
12 return BlocProvider( 16 return BlocProvider(
13 - create: (context) => HomeBloc(), 17 + create: (context) => HomeBloc(PageController(
  18 + initialPage: 0,
  19 + )),
14 child: _HomePageView(), 20 child: _HomePageView(),
15 ); 21 );
16 } 22 }
@@ -23,7 +29,9 @@ class _HomePageView extends StatelessWidget { @@ -23,7 +29,9 @@ class _HomePageView extends StatelessWidget {
23 } else if (type == HeaderActionType.phase) { 29 } else if (type == HeaderActionType.phase) {
24 Navigator.of(AppRouter.context).pushNamed(AppRouteName.lesson); 30 Navigator.of(AppRouter.context).pushNamed(AppRouteName.lesson);
25 } else if (type == HeaderActionType.listen) { 31 } else if (type == HeaderActionType.listen) {
26 - 32 + Navigator.of(AppRouter.context).pushNamed(AppRouteName.listen);
  33 + } else if (type == HeaderActionType.shop) {
  34 +
27 } else { 35 } else {
28 36
29 } 37 }
@@ -33,22 +41,78 @@ class _HomePageView extends StatelessWidget { @@ -33,22 +41,78 @@ class _HomePageView extends StatelessWidget {
33 Widget build(BuildContext context) { 41 Widget build(BuildContext context) {
34 return BlocListener<HomeBloc,HomeState>( 42 return BlocListener<HomeBloc,HomeState>(
35 listener: (context, state){}, 43 listener: (context, state){},
36 - child: Scaffold(  
37 - body: Container(  
38 - color: Colors.white,  
39 - child: Center(  
40 - child: Column(  
41 - children: [  
42 - HomeTabHeaderWidget(  
43 - actionTap: (HeaderActionType type) {  
44 - _headerActionEvent(type);  
45 - },  
46 - ),  
47 - ],  
48 - ),  
49 - ),  
50 - ),  
51 - ), 44 + child: _homeView(),
52 ); 45 );
53 } 46 }
  47 +
  48 + Widget _homeView() => BlocBuilder<HomeBloc,HomeState>(
  49 + builder: (context, state){
  50 + final bloc = BlocProvider.of<HomeBloc>(context);
  51 + return Scaffold(
  52 + body: Container(
  53 + color: Colors.white,
  54 + child: Center(
  55 + child: Column(
  56 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  57 + children: [
  58 + HomeTabHeaderWidget(
  59 + actionTap: (HeaderActionType type) {
  60 + _headerActionEvent(type);
  61 + },
  62 + ),
  63 + Expanded(
  64 + child: PageView.builder(
  65 + itemCount: 10,
  66 + controller: bloc.pageController,
  67 + pageSnapping: false,
  68 + onPageChanged: (int index) {
  69 + EasyLoading.showToast(index.toString());
  70 + },
  71 + itemBuilder: (BuildContext context,int index){
  72 + return const HomeLessonItem();
  73 + // return Container(
  74 + // color:index%2==0?Colors.red:Colors.blue
  75 + // );
  76 + })
  77 + ,
  78 + ),
  79 + SafeArea(
  80 + child: Padding(
  81 + padding: EdgeInsets.symmetric(horizontal: 13.w),
  82 + child: Row(
  83 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  84 + children: [
  85 + SizedBox(
  86 + height: 47.h,
  87 + width: 80.w,
  88 + ),
  89 + Container(
  90 + decoration: BoxDecoration(
  91 + color: Colors.blue,
  92 + borderRadius: BorderRadius.circular(14.5.r),
  93 + ),
  94 + padding: EdgeInsets.symmetric(vertical: 8.h,horizontal: 24.w),
  95 + child: Text(
  96 + '3/67',
  97 + style: TextStyle(
  98 + color: Colors.white,
  99 + fontSize: 12.sp
  100 + ),
  101 + ),
  102 + ),
  103 + Image.asset(
  104 + 'blue-positive'.assetPng,
  105 + height: 47.h,
  106 + width: 80.w,
  107 + ),
  108 + ],
  109 + ),
  110 + ),
  111 + )
  112 + ],
  113 + ),
  114 + ),
  115 + ),
  116 + );
  117 + });
54 } 118 }
55 \ No newline at end of file 119 \ No newline at end of file
lib/home/widgets/home_lesson_item_widget.dart 0 → 100644
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  3 +
  4 +class HomeLessonItem extends StatelessWidget {
  5 + const HomeLessonItem({super.key});
  6 +
  7 + @override
  8 + Widget build(BuildContext context) {
  9 + return SizedBox(
  10 + width: double.infinity,
  11 + child: ListView.builder(
  12 + itemCount: 5,
  13 + scrollDirection: Axis.horizontal,
  14 + physics: const NeverScrollableScrollPhysics(),
  15 + itemBuilder: (BuildContext context,int index){
  16 + return Padding(
  17 + padding: EdgeInsets.symmetric(horizontal: 4.w),
  18 + child: Image.network(
  19 + 'https://img.liblibai.com/web/648331d5a2cb5.png?image_process=format,webp&x-oss-process=image/resize,w_2980,m_lfit/format,webp',
  20 + ),
  21 + );
  22 + }),
  23 + );
  24 + }
  25 +}
0 \ No newline at end of file 26 \ No newline at end of file
lib/home/widgets/home_tab_header_widget.dart
@@ -11,6 +11,8 @@ enum HeaderActionType { @@ -11,6 +11,8 @@ enum HeaderActionType {
11 listen, 11 listen,
12 //购买 12 //购买
13 shop, 13 shop,
  14 + //个人信息
  15 + userinfo
14 } 16 }
15 17
16 class HomeTabHeaderWidget extends StatelessWidget { 18 class HomeTabHeaderWidget extends StatelessWidget {
@@ -29,20 +31,54 @@ class HomeTabHeaderWidget extends StatelessWidget { @@ -29,20 +31,54 @@ class HomeTabHeaderWidget extends StatelessWidget {
29 child: Row( 31 child: Row(
30 children: [ 32 children: [
31 ScreenUtil().bottomBarHeight.horizontalSpace, 33 ScreenUtil().bottomBarHeight.horizontalSpace,
32 - ClipRRect(  
33 - borderRadius:BorderRadius.circular(21),  
34 - child: Image.network(  
35 - 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Faa1c2213-820a-4223-8757-5f8cee318a28%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1688713226&t=192b18a613683bcdc5bd76f65c9ff032',  
36 - height: 42,  
37 - width: 42,  
38 - fit: BoxFit.fill, 34 + GestureDetector(
  35 + onTap: () {
  36 + if(actionTap != null) {
  37 + actionTap!(HeaderActionType.userinfo);
  38 + }
  39 + },
  40 + child: Container(
  41 + decoration: BoxDecoration(
  42 + border: Border.all(
  43 + width: 1.0,
  44 + color: const Color(0xFF140C10),
  45 + ),
  46 + borderRadius: BorderRadius.circular(21),
  47 + ),
  48 + child: const CircleAvatar(
  49 + radius: 21,
  50 + backgroundImage: NetworkImage(
  51 + 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Faa1c2213-820a-4223-8757-5f8cee318a28%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1688713226&t=192b18a613683bcdc5bd76f65c9ff032'
  52 + ),
  53 + ),
39 ), 54 ),
40 ), 55 ),
41 - Container(  
42 - color: Colors.white,  
43 - margin: const EdgeInsets.only(left: 7),  
44 - padding: const EdgeInsets.all(7.0),  
45 - child: const Text('franky'), 56 + GestureDetector(
  57 + onTap: () {
  58 + if(actionTap != null) {
  59 + actionTap!(HeaderActionType.userinfo);
  60 + }
  61 + },
  62 + child: Container(
  63 + margin: const EdgeInsets.only(left: 7),
  64 + padding: const EdgeInsets.all(4.0),
  65 + decoration: BoxDecoration(
  66 + color: Colors.white,
  67 + borderRadius: BorderRadius.circular(2),
  68 + border: Border.all(
  69 + width: 1.0,
  70 + color: const Color(0xFF140C10),
  71 + style: BorderStyle.solid
  72 + ),
  73 + ),
  74 + child: const Text(
  75 + 'franky',
  76 + style: TextStyle(
  77 + color: Color(0xFF333333),
  78 + fontSize: 16
  79 + ),
  80 + ),
  81 + ),
46 ), 82 ),
47 20.horizontalSpace, 83 20.horizontalSpace,
48 const Expanded( 84 const Expanded(
lib/lessons/lesson_page.dart
@@ -41,6 +41,16 @@ class _LessonPageView extends StatelessWidget { @@ -41,6 +41,16 @@ class _LessonPageView extends StatelessWidget {
41 listener: (context, state){}, 41 listener: (context, state){},
42 child: Scaffold( 42 child: Scaffold(
43 appBar: WEAppBar( 43 appBar: WEAppBar(
  44 + leading: IconButton(
  45 + onPressed: (){
  46 + Navigator.pop(context);
  47 + },
  48 + icon: Image.asset(
  49 + 'back'.assetPng,
  50 + height: 43,
  51 + width: 43,
  52 + )
  53 + ),
44 actions: <Widget>[ 54 actions: <Widget>[
45 IconButton( 55 IconButton(
46 icon: Image.asset('shop'.assetPng), 56 icon: Image.asset('shop'.assetPng),
lib/listen/bloc/listen_bloc.dart 0 → 100644
  1 +import 'dart:async';
  2 +
  3 +import 'package:bloc/bloc.dart';
  4 +import 'package:meta/meta.dart';
  5 +
  6 +part 'listen_event.dart';
  7 +part 'listen_state.dart';
  8 +
  9 +class ListenBloc extends Bloc<ListenEvent, ListenState> {
  10 + ListenBloc() : super(ListenInitial()) {
  11 + on<ListenEvent>((event, emit) {
  12 + // TODO: implement event handler
  13 + });
  14 + }
  15 +}
lib/listen/bloc/listen_event.dart 0 → 100644
  1 +part of 'listen_bloc.dart';
  2 +
  3 +@immutable
  4 +abstract class ListenEvent {}
lib/listen/bloc/listen_state.dart 0 → 100644
  1 +part of 'listen_bloc.dart';
  2 +
  3 +@immutable
  4 +abstract class ListenState {}
  5 +
  6 +class ListenInitial extends ListenState {}
lib/listen/listen_page.dart 0 → 100644
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_bloc/flutter_bloc.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +import 'package:wow_english/common/widgets/we_app_bar.dart';
  5 +import 'package:wow_english/listen/bloc/listen_bloc.dart';
  6 +import 'package:wow_english/listen/widgets/listen_item_widget.dart';
  7 +
  8 +class ListenPage extends StatelessWidget {
  9 + const ListenPage({super.key});
  10 +
  11 + @override
  12 + Widget build(BuildContext context) {
  13 + return BlocProvider(
  14 + create: (context) => ListenBloc(),
  15 + child: _ListenPageView(),
  16 + );
  17 + }
  18 +}
  19 +
  20 +class _ListenPageView extends StatelessWidget {
  21 + @override
  22 + Widget build(BuildContext context) {
  23 + return BlocListener<ListenBloc, ListenState>(
  24 + listener: (context, state) {
  25 +
  26 + },
  27 + child: Scaffold(
  28 + appBar: const WEAppBar(
  29 + titleText: '磨耳朵',
  30 + centerTitle: false,
  31 + ),
  32 + body: _listenView(),
  33 + ),
  34 + );
  35 + }
  36 +
  37 + Widget _listenView() => BlocBuilder<ListenBloc, ListenState>(
  38 + builder: (context, state) {
  39 + return ListView.builder(
  40 + itemCount: 10,
  41 + scrollDirection: Axis.horizontal,
  42 + padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h),
  43 + itemBuilder: (BuildContext context,int index){
  44 + return ListenItemWidget(
  45 + isLock: (index < 5),
  46 + clickEvent: (){
  47 +
  48 + });
  49 + });
  50 + });
  51 +}
0 \ No newline at end of file 52 \ No newline at end of file
lib/listen/widgets/listen_item_widget.dart 0 → 100644
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  3 +import 'package:wow_english/common/extension/string_extension.dart';
  4 +
  5 +class ListenItemWidget extends StatelessWidget {
  6 + const ListenItemWidget({super.key, this.isLock = false, required this.clickEvent});
  7 +
  8 + final Function() clickEvent;
  9 +
  10 + final bool isLock;
  11 +
  12 + @override
  13 + Widget build(BuildContext context) {
  14 + return Padding(
  15 + padding: EdgeInsets.symmetric(horizontal: 8.5.w),
  16 + child: Column(
  17 + children: [
  18 + GestureDetector(
  19 + onTap: () {
  20 + if (!isLock) {
  21 + clickEvent();
  22 + }
  23 + },
  24 + child: ClipRRect(
  25 + borderRadius:BorderRadius.circular(90),
  26 + child: Stack(
  27 + alignment:Alignment.center,
  28 + children: [
  29 + Image.network(
  30 + 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Faa1c2213-820a-4223-8757-5f8cee318a28%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1688713226&t=192b18a613683bcdc5bd76f65c9ff032',
  31 + height: 180,
  32 + width: 180,
  33 + fit: BoxFit.fill,
  34 + ),
  35 + Offstage(
  36 + offstage: isLock??false,
  37 + child: Container(
  38 + height: 180,
  39 + width: 180,
  40 + color: const Color.fromRGBO(1, 1, 0, 0.5),
  41 + ),
  42 + ),
  43 + Offstage(
  44 + offstage: isLock,
  45 + child: Image.asset(
  46 + 'listen_lock'.assetPng,
  47 + height: 36,
  48 + width: 41,
  49 + ),
  50 + )
  51 + ],
  52 + ),
  53 + ),
  54 + ),
  55 + 23.verticalSpace,
  56 + Container(
  57 + height: 40.h,
  58 + padding: const EdgeInsets.symmetric(horizontal: 22),
  59 + decoration: BoxDecoration(
  60 + color: const Color(0xFFFFCC00),
  61 + borderRadius: BorderRadius.circular(20.r),
  62 + border: Border.all(
  63 + width: 1.0,
  64 + color: const Color(0xFF333333),
  65 + ),
  66 + ),
  67 + alignment: Alignment.center,
  68 + child: Text(
  69 + 'listen title',
  70 + style: TextStyle(
  71 + fontSize: 15.sp
  72 + ),
  73 + ),
  74 + )
  75 + ],
  76 + ),
  77 + );
  78 + }
  79 +}
0 \ No newline at end of file 80 \ No newline at end of file
lib/pages/page1.dart deleted
1 -import 'package:flutter/material.dart';  
2 -import 'package:wow_english/common/widgets/we_app_bar.dart';  
3 -  
4 -class Page1 extends StatelessWidget {  
5 - const Page1({super.key});  
6 -  
7 - @override  
8 - Widget build(BuildContext context) {  
9 - return const Scaffold(  
10 - appBar: WEAppBar(  
11 - titleText: '页面1',  
12 - ),  
13 - body:Center(  
14 - child: Text('页面1'),  
15 - ),  
16 - );  
17 - }  
18 -}  
19 \ No newline at end of file 0 \ No newline at end of file
lib/pages/page2.dart deleted
1 -import 'package:flutter/material.dart';  
2 -import 'package:wow_english/common/widgets/we_app_bar.dart';  
3 -  
4 -class Page2 extends StatelessWidget {  
5 - const Page2({super.key});  
6 -  
7 - @override  
8 - Widget build(BuildContext context) {  
9 - return const Scaffold(  
10 - appBar: WEAppBar(  
11 - titleText: '页面2',  
12 - ),  
13 - body:Center(  
14 - child: Text('页面2'),  
15 - ),  
16 - );  
17 - }  
18 -}  
19 \ No newline at end of file 0 \ No newline at end of file
lib/route/route.dart
@@ -4,6 +4,7 @@ import &#39;package:wow_english/app/splash_page.dart&#39;; @@ -4,6 +4,7 @@ import &#39;package:wow_english/app/splash_page.dart&#39;;
4 import 'package:wow_english/common/pages/wow_web_page.dart'; 4 import 'package:wow_english/common/pages/wow_web_page.dart';
5 import 'package:wow_english/home/home_page.dart'; 5 import 'package:wow_english/home/home_page.dart';
6 import 'package:wow_english/lessons/lesson_page.dart'; 6 import 'package:wow_english/lessons/lesson_page.dart';
  7 +import 'package:wow_english/listen/listen_page.dart';
7 import 'package:wow_english/login/forgetpwd/forget_password_home_page.dart'; 8 import 'package:wow_english/login/forgetpwd/forget_password_home_page.dart';
8 import 'package:wow_english/login/loginpage/login_page.dart'; 9 import 'package:wow_english/login/loginpage/login_page.dart';
9 import 'package:wow_english/login/setpwd/set_pwd_page.dart'; 10 import 'package:wow_english/login/setpwd/set_pwd_page.dart';
@@ -18,6 +19,7 @@ class AppRouteName { @@ -18,6 +19,7 @@ class AppRouteName {
18 static const String setPwd = 'setPwd'; 19 static const String setPwd = 'setPwd';
19 static const String webView = 'webView'; 20 static const String webView = 'webView';
20 static const String lesson = 'lesson'; 21 static const String lesson = 'lesson';
  22 + static const String listen = 'listen';
21 static const String tab = '/'; 23 static const String tab = '/';
22 } 24 }
23 25
@@ -42,6 +44,8 @@ class AppRouter { @@ -42,6 +44,8 @@ class AppRouter {
42 return CupertinoPageRoute(builder: (_) => const ForgetPasswordHomePage()); 44 return CupertinoPageRoute(builder: (_) => const ForgetPasswordHomePage());
43 case AppRouteName.lesson: 45 case AppRouteName.lesson:
44 return CupertinoPageRoute(builder: (_) => const LessonPage()); 46 return CupertinoPageRoute(builder: (_) => const LessonPage());
  47 + case AppRouteName.listen:
  48 + return CupertinoPageRoute(builder: (_) => const ListenPage());
45 case AppRouteName.setPwd: 49 case AppRouteName.setPwd:
46 final phoneNum = (settings.arguments as Map)['phoneNumber'] as String; 50 final phoneNum = (settings.arguments as Map)['phoneNumber'] as String;
47 return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum)); 51 return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum));
lib/tab/tab_page.dart
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 2 import 'package:flutter_bloc/flutter_bloc.dart';
3 -import 'package:wow_english/Pages/page1.dart';  
4 -import 'package:wow_english/Pages/page2.dart'; 3 +import 'package:wow_english/home/home_page.dart';
  4 +import 'package:wow_english/lessons/lesson_page.dart';
5 import 'package:wow_english/tab/blocs/tab_bloc.dart'; 5 import 'package:wow_english/tab/blocs/tab_bloc.dart';
6 6
7 class TabPage extends StatelessWidget { 7 class TabPage extends StatelessWidget {
8 const TabPage({super.key}); 8 const TabPage({super.key});
9 9
10 final _pages =const <Widget>[ 10 final _pages =const <Widget>[
11 - Page1(),  
12 - Page2() 11 + HomePage(),
  12 + LessonPage()
13 ]; 13 ];
14 14
15 final _tabIcons = const <Icon>[ 15 final _tabIcons = const <Icon>[