From 9d080046d04cf46c1d3c8429f72e0c760893b5c1 Mon Sep 17 00:00:00 2001 From: lcy <2503978335@qq.com> Date: Thu, 15 Jun 2023 16:04:26 +0800 Subject: [PATCH] feat:视频跟读逻辑 --- assets/images/gendubeij.png | Bin 0 -> 49858 bytes assets/images/gendubeij_mengban.png | Bin 0 -> 24091 bytes assets/images/star_dark.png | Bin 0 -> 2953 bytes assets/images/star_light.png | Bin 0 -> 2135 bytes lib/home/home_page.dart | 2 +- lib/repeatafter/bloc/repeat_after_bloc.dart | 23 +++++++++++++++++++++++ lib/repeatafter/bloc/repeat_after_event.dart | 4 ++++ lib/repeatafter/bloc/repeat_after_state.dart | 8 ++++++++ lib/repeatafter/repeat_after_page.dart | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/repeatafter/widgets/repeat_after_item.dart | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/route/route.dart | 4 ++++ 11 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 assets/images/gendubeij.png create mode 100644 assets/images/gendubeij_mengban.png create mode 100644 assets/images/star_dark.png create mode 100644 assets/images/star_light.png create mode 100644 lib/repeatafter/bloc/repeat_after_bloc.dart create mode 100644 lib/repeatafter/bloc/repeat_after_event.dart create mode 100644 lib/repeatafter/bloc/repeat_after_state.dart create mode 100644 lib/repeatafter/repeat_after_page.dart create mode 100644 lib/repeatafter/widgets/repeat_after_item.dart diff --git a/assets/images/gendubeij.png b/assets/images/gendubeij.png new file mode 100644 index 0000000..37c05b0 Binary files /dev/null and b/assets/images/gendubeij.png differ diff --git a/assets/images/gendubeij_mengban.png b/assets/images/gendubeij_mengban.png new file mode 100644 index 0000000..ee618ae Binary files /dev/null and b/assets/images/gendubeij_mengban.png differ diff --git a/assets/images/star_dark.png b/assets/images/star_dark.png new file mode 100644 index 0000000..280ec46 Binary files /dev/null and b/assets/images/star_dark.png differ diff --git a/assets/images/star_light.png b/assets/images/star_light.png new file mode 100644 index 0000000..8251f1a Binary files /dev/null and b/assets/images/star_light.png differ diff --git a/lib/home/home_page.dart b/lib/home/home_page.dart index 5b07eb4..fe1b9f8 100644 --- a/lib/home/home_page.dart +++ b/lib/home/home_page.dart @@ -25,7 +25,7 @@ class HomePage extends StatelessWidget { class _HomePageView extends StatelessWidget { void _headerActionEvent(HeaderActionType type) { if (type == HeaderActionType.video) { - + Navigator.of(AppRouter.context).pushNamed(AppRouteName.reAfter); } else if (type == HeaderActionType.phase) { Navigator.of(AppRouter.context).pushNamed(AppRouteName.lesson); } else if (type == HeaderActionType.listen) { diff --git a/lib/repeatafter/bloc/repeat_after_bloc.dart b/lib/repeatafter/bloc/repeat_after_bloc.dart new file mode 100644 index 0000000..1d42860 --- /dev/null +++ b/lib/repeatafter/bloc/repeat_after_bloc.dart @@ -0,0 +1,23 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; + +part 'repeat_after_event.dart'; +part 'repeat_after_state.dart'; + +class RepeatAfterBloc extends Bloc { + RepeatAfterBloc() : super(RepeatAfterInitial()) { + on((event, emit) { + // TODO: implement event handler + }); + } + + + Future requestData() async { + EasyLoading.show(); + Future.delayed(const Duration(milliseconds: 2000),(){ + EasyLoading.dismiss(); + emit(RequestDataState()); + }); + } +} diff --git a/lib/repeatafter/bloc/repeat_after_event.dart b/lib/repeatafter/bloc/repeat_after_event.dart new file mode 100644 index 0000000..3a46031 --- /dev/null +++ b/lib/repeatafter/bloc/repeat_after_event.dart @@ -0,0 +1,4 @@ +part of 'repeat_after_bloc.dart'; + +@immutable +abstract class RepeatAfterEvent {} diff --git a/lib/repeatafter/bloc/repeat_after_state.dart b/lib/repeatafter/bloc/repeat_after_state.dart new file mode 100644 index 0000000..e8c710f --- /dev/null +++ b/lib/repeatafter/bloc/repeat_after_state.dart @@ -0,0 +1,8 @@ +part of 'repeat_after_bloc.dart'; + +@immutable +abstract class RepeatAfterState {} + +class RepeatAfterInitial extends RepeatAfterState {} + +class RequestDataState extends RepeatAfterState {} diff --git a/lib/repeatafter/repeat_after_page.dart b/lib/repeatafter/repeat_after_page.dart new file mode 100644 index 0000000..0dc36ca --- /dev/null +++ b/lib/repeatafter/repeat_after_page.dart @@ -0,0 +1,65 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:wow_english/common/widgets/we_app_bar.dart'; +import 'package:wow_english/repeatafter/widgets/repeat_after_item.dart'; + +import 'bloc/repeat_after_bloc.dart'; + +class RepeatAfterPage extends StatelessWidget { + const RepeatAfterPage({super.key}); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => RepeatAfterBloc()..requestData(), + child: _RepeatAfterPageView(), + ); + } +} + +class _RepeatAfterPageView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BlocListener( + listener: (context, state) { + if (state is RequestDataState) { + EasyLoading.showToast('网络请求结束'); + } + }, + child: _repeatAfterView(), + ); + } + + Widget _repeatAfterView() => BlocBuilder( + builder: (context, state) { + return Scaffold( + appBar: const WEAppBar( + titleText: '视频跟读', + centerTitle: false, + ), + body: SafeArea( + child: Container( + alignment: Alignment.center, + child: ListView.builder( + itemCount: 10, + scrollDirection: Axis.horizontal, + itemBuilder: (BuildContext context,int index){ + bool unLock = index%3==0; + return RepeatAfterItem( + unLock: unLock, + tapEvent: () { + + }, + starNumber: !unLock?0:Random().nextInt(5) + ); + }), + ), + ), + ); + }, + ); +} + diff --git a/lib/repeatafter/widgets/repeat_after_item.dart b/lib/repeatafter/widgets/repeat_after_item.dart new file mode 100644 index 0000000..c898b48 --- /dev/null +++ b/lib/repeatafter/widgets/repeat_after_item.dart @@ -0,0 +1,137 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:wow_english/common/extension/string_extension.dart'; + +class RepeatAfterItem extends StatelessWidget { + const RepeatAfterItem({super.key, required this.starNumber, required this.unLock, required this.tapEvent}); + //分数 + final int starNumber; + //是否解锁 + final bool unLock; + + final Function() tapEvent; + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric( + horizontal: 10.w + ), + child: GestureDetector( + onTap: (){ + if(unLock) { + tapEvent(); + } + }, + child: Stack( + children: [ + _modelInfoWidget(context), + _lockWidget() + ], + ), + ), + ); + } + + Widget _modelInfoWidget(BuildContext context) { + return Container( + width: 162.w, + height: 235.h, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + 'gendubeij'.assetPng + ), + fit: BoxFit.fill + ) + ), + padding: EdgeInsets.symmetric(horizontal: 11.w,vertical: 13.h), + alignment: Alignment.center, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Image.network( + 'https://img.liblibai.com/web/648331d033b41.png?image_process=format,webp&x-oss-process=image/resize,w_2980,m_lfit/format,webp', + height: 100.h, + width: 140.w, + fit: BoxFit.fitWidth, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Image.asset( + starNumber >= 1 ? 'star_light'.assetPng:'star_dark'.assetPng, + width: 23.w, + height: 21.h, + ), + Image.asset( + starNumber >= 2 ? 'star_light'.assetPng:'star_dark'.assetPng, + width: 23.w, + height: 21.h, + ), + Image.asset( + starNumber >= 3 ? 'star_light'.assetPng:'star_dark'.assetPng, + width: 23.w, + height: 21.h, + ), + Image.asset( + starNumber >= 4 ? 'star_light'.assetPng:'star_dark'.assetPng, + width: 23.w, + height: 21.h, + ), + Image.asset( + starNumber >= 5 ? 'star_light'.assetPng:'star_dark'.assetPng, + width: 23.w, + height: 21.h, + ), + ], + ), + Container( + height: 35.h, + width: double.infinity, + decoration: BoxDecoration( + color: const Color(0xFFFFCC00), + borderRadius: BorderRadius.circular(5.r), + border: Border.all( + width: 1.0, + color: const Color(0xFF333333), + ), + ), + alignment: Alignment.center, + child: Text( + 'video title', + style: TextStyle( + fontSize: 16.sp, + color: const Color(0xFF333333) + ), + ), + ) + ], + ), + ); + } + + Widget _lockWidget() { + return Offstage( + offstage: unLock, + child: Container( + width: 162.w, + height: 235.h, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + 'gendubeij_mengban'.assetPng + ), + fit: BoxFit.fill + ) + ), + alignment: Alignment.center, + child: Image.asset( + 'listen_lock'.assetPng, + height: 36.h, + width: 41.w, + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/route/route.dart b/lib/route/route.dart index 6a75dcd..132b629 100644 --- a/lib/route/route.dart +++ b/lib/route/route.dart @@ -8,6 +8,7 @@ import 'package:wow_english/listen/listen_page.dart'; import 'package:wow_english/login/forgetpwd/forget_password_home_page.dart'; import 'package:wow_english/login/loginpage/login_page.dart'; import 'package:wow_english/login/setpwd/set_pwd_page.dart'; +import 'package:wow_english/repeatafter/repeat_after_page.dart'; import 'package:wow_english/shop/exchane/exchange_lesson_page.dart'; import 'package:wow_english/shop/exchangelist/exchange_lesson_list_page.dart'; import 'package:wow_english/shop/home/shop_home_page.dart'; @@ -26,6 +27,7 @@ class AppRouteName { static const String shop = 'shop'; static const String exLesson = 'exLesson'; static const String exList = 'exList'; + static const String reAfter = 'reAfter'; static const String tab = '/'; } @@ -58,6 +60,8 @@ class AppRouter { return CupertinoPageRoute(builder: (_) => const ExchangeLessonPage()); case AppRouteName.exList: return CupertinoPageRoute(builder: (_) => const ExchangeLessonListPage()); + case AppRouteName.reAfter: + return CupertinoPageRoute(builder: (_) => const RepeatAfterPage()); case AppRouteName.setPwd: final phoneNum = (settings.arguments as Map)['phoneNumber'] as String; return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum)); -- libgit2 0.22.2