import 'package:easy_refresh/easy_refresh.dart'; import 'package:flutter/material.dart'; import 'package:flutter_kinetra/kt_model/kt_home_category_bean.dart'; import 'package:flutter_kinetra/kt_pages/kt_home/logic.dart'; import 'package:flutter_kinetra/kt_pages/kt_routes.dart'; import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart'; import 'package:flutter_kinetra/kt_widgets/kt_status_widget.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import '../../kt_model/kt_short_video_bean.dart'; import '../../kt_widgets/kt_network_image.dart'; class KtHomePage extends StatefulWidget { const KtHomePage({super.key}); @override State createState() => _KtHomePageState(); } class _KtHomePageState extends State with TickerProviderStateMixin, AutomaticKeepAliveClientMixin { final logic = Get.put(KtHomeLogic()); final state = Get.find().state; late TabController tabCtrl; TabController? categoryTabCtrl; @override Widget build(BuildContext context) { super.build(context); return GetBuilder( assignId: true, builder: (ctrl) { if (state.loadStatus == KtLoadStatusType.loadFailed) { return Center( child: KtStatusWidget( type: KtErrorStatusType.nothingYet, onPressed: logic.refreshData, ), ); } return Stack( children: [ Container( width: ScreenUtil().screenWidth, height: ScreenUtil().screenHeight, padding: EdgeInsets.only(top: kToolbarHeight), decoration: BoxDecoration( image: DecorationImage( image: AssetImage('bg1.png'.ktIcon), fit: BoxFit.fill, ), ), child: EasyRefresh( controller: logic.easyRefreshController, header: MaterialHeader(), footer: MaterialFooter(), onRefresh: () => logic.refreshData(), // onLoad: () => logic.loadMoreData(), canLoadAfterNoMore: false, child: NestedScrollView( headerSliverBuilder: (context, _) => [ SliverToBoxAdapter(child: topAdapterView()), ], body: discoverView(), ), ), ), ], ); }, ); } Widget topAdapterView() { return Column(children: [searchView(), topTrendView(), picksView()]); } Widget searchView() { return Container( padding: EdgeInsets.symmetric(horizontal: 15.w), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( width: 235.w, height: 22.w, padding: EdgeInsets.only(right: 7.w), alignment: Alignment.centerRight, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('home_top_slogan.png'.ktIcon), fit: BoxFit.fill, ), ), child: Text( 'Get Hooked in Seconds', style: TextStyle( fontSize: 11.sp, fontWeight: FontWeight.w600, fontStyle: FontStyle.italic, color: Colors.white, ), ), ), GestureDetector( onTap: () => Get.toNamed(KtRoutes.search), child: Image.asset('ic_search.png'.ktIcon, width: 34.w), ), ], ), ); } Widget topTrendView() { return GetBuilder( id: 'trend', builder: (ctrl) { if (state.mostSearchedList.isEmpty) return Container(); return Container( width: ScreenUtil().screenWidth, height: 129.h, padding: EdgeInsets.fromLTRB(29.w, 24.w, 17.w, 15.h), decoration: BoxDecoration( image: DecorationImage( image: AssetImage('home_top.png'.ktIcon), fit: BoxFit.fill, ), ), child: Row( children: [ Column( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.start, children: [ GestureDetector( onTap: () => Get.toNamed(KtRoutes.search), child: Row( children: [ Stack( alignment: Alignment.bottomCenter, children: [ Image.asset('text_bg.png'.ktIcon, height: 17.w), Text( 'Trend Cyclone', style: TextStyle( fontSize: 14.sp, color: Color(0xFF1E1E20), fontWeight: FontWeight.w800, ), ), ], ), Image.asset('ic_right.png'.ktIcon, width: 10.w), ], ), ), SizedBox(height: 5.w), Text( 'Everyone\'s Watching', style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w400, color: Color(0xFFAEAEAE), ), ), ], ), SizedBox(width: 15.w), Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ...state.mostSearchedList.map( (item) => GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': item.shortPlayId, 'imageUrl': item.imageUrl ?? '', }, ), child: Container( padding: EdgeInsets.symmetric(vertical: 4.w), child: Row( children: [ Image.asset('ic_star.png'.ktIcon, width: 14.w), SizedBox(width: 3.w), SizedBox( width: 162.w, child: Text( '${item.name}', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 13.sp, color: Colors.black, fontWeight: FontWeight.w500, ), ), ), ], ), ), ), ), SizedBox(height: 2.w), ], ), ], ), ); }, ); } Widget picksView() { return GetBuilder( builder: (ctrl) { if (state.bannerList.isEmpty && state.topPickList.isEmpty) { return Container(); } return Container( margin: EdgeInsets.only(bottom: 18.w, top: 10.w), child: Row( children: [ SizedBox(width: 15.w), if (state.bannerList.isNotEmpty) Container( width: 218.w, height: 160.w, padding: EdgeInsets.only(top: 3.w), decoration: BoxDecoration( border: Border.all(color: Colors.white, width: 4.w), borderRadius: BorderRadius.circular(10.w), gradient: LinearGradient( colors: [Color(0xFFDAEEFE), Colors.white, Colors.white], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), child: Column( children: [ Row( children: [ SizedBox(width: 4.w), Text( 'Addictive Picks', style: TextStyle( fontSize: 15.sp, color: Colors.black, fontStyle: FontStyle.italic, fontWeight: FontWeight.w800, ), ), const Spacer(), Image.asset('ic_right_arr.png'.ktIcon, width: 17.w), SizedBox(width: 4.w), ], ), SizedBox(height: 8.w), SizedBox( height: 117.w, child: ListView.separated( padding: EdgeInsets.only(left: 2.w), scrollDirection: Axis.horizontal, itemBuilder: (context, index) => GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': state.bannerList[index].shortPlayId, 'imageUrl': state.bannerList[index].imageUrl ?? '', }, ), child: KtNetworkImage( imageUrl: state.bannerList[index].imageUrl ?? '', borderRadius: BorderRadius.circular(6.w), ), ), separatorBuilder: (_, __) => SizedBox(width: 5.w), itemCount: state.bannerList.length, ), ), ], ), ), const Spacer(), if (state.topPickList.isNotEmpty) Stack( children: [ GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': state.topPickList.first.shortPlayId, 'imageUrl': state.topPickList.first.imageUrl ?? '', }, ), child: Container( width: 120.w, height: 160.w, decoration: BoxDecoration( border: Border.all(color: Colors.white, width: 4.w), borderRadius: BorderRadius.circular(10.w), gradient: LinearGradient( colors: [ Color(0xFFDAEEFE), Colors.white, Colors.white, ], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), child: KtNetworkImage( width: 112.w, height: 152.w, imageUrl: state.topPickList.first.imageUrl ?? '', borderRadius: BorderRadius.circular(6.w), ), ), ), Container( width: 104.w, margin: EdgeInsets.only(top: 7.w, left: 8.w, right: 8.w), child: Row( children: [ Text( 'Top 1', style: TextStyle( fontSize: 15.sp, color: Colors.black, fontStyle: FontStyle.italic, fontWeight: FontWeight.w800, ), ), const Spacer(), Image.asset('ic_right_arr.png'.ktIcon, width: 17.w), ], ), ), ], ), SizedBox(width: 15.w), ], ), ); }, ); } Widget discoverView() { return GetBuilder( builder: (ctrl) { return Column( children: [ Stack( alignment: state.selDiscover == 1 ? Alignment.centerLeft : Alignment.centerRight, children: [ Container( width: double.infinity, alignment: state.selDiscover == 0 ? Alignment.centerLeft : Alignment.centerRight, child: Container( width: 214.w, height: 50.w, margin: state.selDiscover == 0 ? EdgeInsets.only(right: 15.w) : EdgeInsets.only(left: 15.w), decoration: BoxDecoration( image: DecorationImage( image: AssetImage( state.selDiscover == 0 ? 'home_left_sel.png'.ktIcon : 'home_right_sel.png'.ktIcon, ), fit: BoxFit.fill, ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset('ip.png'.ktIcon, width: 32.w), SizedBox(width: 8.w), Stack( alignment: Alignment.bottomCenter, children: [ Image.asset( 'text_bg_discover.png'.ktIcon, height: 17.w, width: 70.w, ), Padding( padding: EdgeInsets.only(bottom: 4.w), child: Text( state.selDiscover == 0 ? 'Discover' : 'Categories', style: TextStyle( fontSize: 16.sp, color: Colors.black, fontStyle: FontStyle.italic, fontWeight: FontWeight.w800, ), ), ), ], ), ], ), ), ), GestureDetector( onTap: () { state.selDiscover = state.selDiscover == 0 ? 1 : 0; setState(() {}); }, child: Container( width: 168.w, height: 50.w, padding: EdgeInsets.only(top: 10.w), margin: state.selDiscover == 0 ? EdgeInsets.only(right: 15.w) : EdgeInsets.only(left: 15.w), decoration: BoxDecoration( image: DecorationImage( image: AssetImage( state.selDiscover == 1 ? 'home_left.png'.ktIcon : 'home_right.png'.ktIcon, ), fit: BoxFit.fill, ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( state.selDiscover == 1 ? 'Discover' : 'Categories', style: TextStyle( fontSize: 16.sp, color: Colors.black, fontStyle: FontStyle.italic, fontWeight: FontWeight.w800, ), ), ], ), ), ), ], ), Expanded( child: Container( width: double.infinity, color: Colors.white, padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 10.w), child: Column( children: [ state.selDiscover == 0 ? Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ...state.typeList.map( (item) => GestureDetector( onTap: () { state.selType = item; setState(() {}); tabCtrl.animateTo( state.typeList.indexOf(item), ); }, child: Container( width: (ScreenUtil().screenWidth - 42.w) / 3, padding: EdgeInsets.symmetric( vertical: 8.w, ), alignment: Alignment.center, decoration: BoxDecoration( color: Color(0xFFF6F6F6), borderRadius: BorderRadius.circular(8.w), image: state.selType == item ? DecorationImage( image: AssetImage( 'home_item_sel.png'.ktIcon, ), fit: BoxFit.fill, ) : null, ), child: Text( item, style: TextStyle( fontSize: 14.sp, color: Color(0xFF1E1E20), fontWeight: state.selType == item ? FontWeight.w600 : FontWeight.w400, ), ), ), ), ), ], ) : categoryView(), SizedBox(height: 14.w), Expanded(child: bottomVideoView()), ], ), ), ), ], ); }, ); } Widget categoryView() { return GetBuilder( id: "category-items", builder: (ctrl) { return SizedBox( height: 35.w, child: ListView.separated( scrollDirection: Axis.horizontal, padding: EdgeInsets.zero, itemBuilder: (context, index) { KtHomeCategoryBean item = state.categoryList[index]; return GestureDetector( onTap: () { if (state.selCategoryId == item.categoryId!) return; state.selCategoryId = item.categoryId!; categoryTabCtrl?.animateTo(state.categoryList.indexOf(item)); logic.getCategoryVideoList(isRefresh: true); }, child: Container( width: (ScreenUtil().screenWidth - 42.w) / 3, padding: EdgeInsets.symmetric(vertical: 8.w), alignment: Alignment.center, decoration: BoxDecoration( color: Color(0xFFF6F6F6), borderRadius: BorderRadius.circular(8.w), image: state.selCategoryId == item.categoryId ? DecorationImage( image: AssetImage('home_item_sel.png'.ktIcon), fit: BoxFit.fill, ) : null, ), child: SizedBox( width: ((ScreenUtil().screenWidth - 42.w) / 3) - 4.w, child: Text( textAlign: TextAlign.center, item.categoryName ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 14.sp, color: Color(0xFF1E1E20), fontWeight: state.selCategoryId == item.categoryId ? FontWeight.w600 : FontWeight.w400, ), ), ), ), ); }, separatorBuilder: (_, __) => SizedBox(width: 6.w), itemCount: state.categoryList.length, ), ); }, ); } Widget bottomVideoView() { if (state.selDiscover == 0) { return Expanded( child: TabBarView( controller: tabCtrl, physics: NeverScrollableScrollPhysics(), children: [hotRisingView(), topChartView(), freshDropView()], ), ); // return [hotRisingView(), topChartView(), freshDropView()][state.typeList // .indexOf(state.selType)]; } else { categoryTabCtrl ??= TabController( length: state.categoryList.length, vsync: this, ); return Expanded( child: TabBarView( controller: categoryTabCtrl, physics: NeverScrollableScrollPhysics(), children: List.generate( state.categoryList.length, (index) => categoryVideoView(index), ), ), ); } } Widget hotRisingView() { return GetBuilder( builder: (ctrl) { return GridView.builder( padding: EdgeInsets.only(bottom: 16.w), shrinkWrap: true, // physics: NeverScrollableScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: 10.w, crossAxisSpacing: 7.w, childAspectRatio: 169 / 219, ), itemCount: state.hotList.length, itemBuilder: (BuildContext context, int index) { KtShortVideoBean video = state.hotList[index]; return GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': video.shortPlayId, 'imageUrl': video.imageUrl ?? '', }, ), child: Container( width: 169.w, height: 219.w, padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Color(0xFFF5F5F5), borderRadius: BorderRadius.circular(12.w), ), child: Stack( clipBehavior: Clip.none, children: [ Container( width: 149.w, height: 199.w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.w), ), child: KtNetworkImage( imageUrl: video.imageUrl ?? '', borderRadius: BorderRadius.circular(6.w), ), ), Positioned( top: 4.w, left: 4.w, child: Image.asset('ic_fire.png'.ktIcon, width: 20.w), ), Positioned( top: -10.w, right: -11.w, child: Image.asset( 'ic_rise_right.png'.ktIcon, width: 30.w, ), ), Positioned( bottom: -10.w, left: -16.w, child: Container( width: 181.w, height: 55.w, alignment: Alignment.bottomCenter, padding: EdgeInsets.only( left: 10.w, right: 14.w, bottom: 6.w, ), decoration: BoxDecoration( image: DecorationImage( image: AssetImage('ic_rise_bottom.png'.ktIcon), fit: BoxFit.fill, ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end, children: [ SizedBox( width: 120.w, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.end, children: [ Text( video.name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w400, color: Color(0xFF1E1E20), ), ), Text( video.category?.first ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10.sp, fontWeight: FontWeight.w400, color: Color(0xFF79C900), ), ), ], ), ), Image.asset('ic_rise_play.png'.ktIcon, width: 30.w), ], ), ), ), ], ), ), ); }, ); }, ); } Widget topChartView() { return GetBuilder( builder: (ctrl) { return ListView( padding: EdgeInsets.zero, children: [ Container( width: ScreenUtil().screenWidth - 30.w, height: 224.w, padding: EdgeInsets.all(10.w), decoration: BoxDecoration( image: DecorationImage(image: AssetImage('top_bg.png'.ktIcon)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end, children: [ GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': state.topPickList[1].shortPlayId, 'imageUrl': state.topPickList[1].imageUrl ?? '', }, ), child: Stack( alignment: Alignment.bottomCenter, children: [ Stack( alignment: Alignment.bottomCenter, children: [ Container( margin: EdgeInsets.only(bottom: 10.w), child: Image.asset( 'top_bottom_bg.png'.ktIcon, width: 90.w, height: 55.w, ), ), Container( width: 33.w, height: 33.w, alignment: Alignment.center, margin: EdgeInsets.only(bottom: 12.w), decoration: BoxDecoration( image: DecorationImage( image: AssetImage('top_2.png'.ktIcon), fit: BoxFit.fill, ), ), child: Text( '2', style: TextStyle( fontSize: 12.sp, color: Colors.black, fontWeight: FontWeight.w800, fontStyle: FontStyle.italic, ), ), ), ], ), Stack( alignment: Alignment.bottomCenter, clipBehavior: Clip.none, children: [ Container( width: 80.w, height: 107.w, margin: EdgeInsets.only(bottom: 56.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.w), border: Border.all( width: 2.w, color: Colors.white, ), ), child: KtNetworkImage( imageUrl: state.topPickList[1].imageUrl ?? '', borderRadius: BorderRadius.circular(8.w), ), ), Container( width: 90.w, height: 18.w, margin: EdgeInsets.only(bottom: 56.w), padding: EdgeInsets.symmetric( vertical: 2.w, horizontal: 4.w, ), alignment: Alignment.center, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(100), ), child: Text( state.topPickList[1].name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10.sp, color: Color(0xFF1E1E20), ), ), ), ], ), ], ), ), GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': state.topPickList.first.shortPlayId, 'imageUrl': state.topPickList.first.imageUrl ?? '', }, ), child: Stack( alignment: Alignment.bottomCenter, children: [ Stack( alignment: Alignment.bottomCenter, children: [ Image.asset( 'top_bottom_bg.png'.ktIcon, width: 130.w, height: 80.w, ), Container( width: 46.w, height: 46.w, margin: EdgeInsets.only(bottom: 2.w), alignment: Alignment.center, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('top_1.png'.ktIcon), fit: BoxFit.fill, ), ), child: Text( '1', style: TextStyle( fontSize: 16.sp, color: Colors.black, fontWeight: FontWeight.w800, fontStyle: FontStyle.italic, ), ), ), ], ), Stack( alignment: Alignment.bottomCenter, clipBehavior: Clip.none, children: [ Container( width: 104.w, height: 138.w, margin: EdgeInsets.only(bottom: 66.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.w), border: Border.all( width: 2.w, color: Colors.white, ), ), child: KtNetworkImage( imageUrl: state.topPickList.first.imageUrl ?? '', borderRadius: BorderRadius.circular(8.w), ), ), Container( width: 120.w, height: 18.w, margin: EdgeInsets.only(bottom: 66.w), padding: EdgeInsets.symmetric( vertical: 2.w, horizontal: 4.w, ), alignment: Alignment.center, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(100), ), child: Text( state.topPickList.first.name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10.sp, color: Color(0xFF1E1E20), ), ), ), ], ), ], ), ), GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': state.topPickList[2].shortPlayId, 'imageUrl': state.topPickList[2].imageUrl ?? '', }, ), child: Stack( alignment: Alignment.bottomCenter, children: [ Stack( alignment: Alignment.bottomCenter, children: [ Container( margin: EdgeInsets.only(bottom: 10.w), child: Image.asset( 'top_bottom_bg.png'.ktIcon, width: 90.w, height: 55.w, ), ), Container( width: 33.w, height: 33.w, margin: EdgeInsets.only(bottom: 12.w), alignment: Alignment.center, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('top_3.png'.ktIcon), fit: BoxFit.fill, ), ), child: Text( '3', style: TextStyle( fontSize: 12.sp, color: Colors.black, fontWeight: FontWeight.w800, fontStyle: FontStyle.italic, ), ), ), ], ), Stack( alignment: Alignment.bottomCenter, clipBehavior: Clip.none, children: [ Container( width: 80.w, height: 107.w, margin: EdgeInsets.only(bottom: 56.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.w), border: Border.all( width: 2.w, color: Colors.white, ), ), child: KtNetworkImage( imageUrl: state.topPickList[2].imageUrl ?? '', borderRadius: BorderRadius.circular(8.w), ), ), Container( width: 90.w, height: 18.w, margin: EdgeInsets.only(bottom: 56.w), padding: EdgeInsets.symmetric( vertical: 2.w, horizontal: 4.w, ), alignment: Alignment.center, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(100), ), child: Text( state.topPickList[2].name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10.sp, color: Color(0xFF1E1E20), ), ), ), ], ), ], ), ), ], ), ), SizedBox(height: 10.w), if (state.topPickList.length > 3) ListView.separated( padding: EdgeInsets.zero, shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: state.topPickList.length - 3, itemBuilder: (BuildContext context, int index) { KtShortVideoBean video = state.topPickList[index + 3]; return GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': video.shortPlayId, 'imageUrl': video.imageUrl ?? '', }, ), child: Container( width: ScreenUtil().screenWidth - 30.w, padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Color(0xFFF5F5F5), borderRadius: BorderRadius.circular(14.w), ), child: Row( children: [ Stack( clipBehavior: Clip.none, alignment: Alignment.topLeft, children: [ KtNetworkImage( imageUrl: video.imageUrl ?? '', width: 100.w, height: 127.w, borderRadius: BorderRadius.circular(12.w), ), Container( width: 24.w, height: 24.w, alignment: Alignment.center, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('top_other.png'.ktIcon), fit: BoxFit.fill, ), ), child: Text( '${index + 4}', style: TextStyle( fontSize: 12.sp, color: Colors.black, fontWeight: FontWeight.w800, fontStyle: FontStyle.italic, ), ), ), ], ), SizedBox(width: 12.w), SizedBox( width: 200.w, height: 127.w, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( video.name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w500, color: Color(0xFF1E1E20), ), ), Text( video.categoryList?.first.name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w400, color: Color(0xFF79C900), ), ), Text( video.description ?? '', maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10.sp, fontWeight: FontWeight.w400, color: Color(0xFF5E5E5E), ), ), Row( children: [ Container( padding: EdgeInsets.symmetric( horizontal: 14.w, vertical: 7.w, ), decoration: BoxDecoration( color: Color(0xFF1E1E20), borderRadius: BorderRadius.circular( 100, ), ), child: Row( children: [ Image.asset( 'ic_top_play.png'.ktIcon, width: 16.w, ), SizedBox(width: 4.w), Text( 'Play', style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w500, color: Color(0xFFA7F62F), ), ), ], ), ), ], ), ], ), ), ], ), ), ); }, separatorBuilder: (_, __) => SizedBox(height: 10.w), ), ], ); }, ); } Widget freshDropView() { return GetBuilder( builder: (ctrl) { return ListView.separated( padding: EdgeInsets.only(bottom: 20.w), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: state.arrivalList.length, itemBuilder: (BuildContext context, int index) { KtShortVideoBean video = state.arrivalList[index]; if (index == 0) { return GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': video.shortPlayId, 'imageUrl': video.imageUrl ?? '', }, ), child: Container( width: ScreenUtil().screenWidth - 30.w, decoration: BoxDecoration( color: Color(0xFFFFFBCA), borderRadius: BorderRadius.circular(14.w), ), child: Column( children: [ SizedBox(height: 10.w), Row( children: [ SizedBox(width: 10.w), Image.asset('ic_drop_dot.png'.ktIcon, width: 12.w), SizedBox(width: 5.w), Text( 'Today\'s Drops', style: TextStyle( fontSize: 15.sp, fontWeight: FontWeight.w700, color: Colors.black, fontStyle: FontStyle.italic, ), ), Container( height: 12.w, width: 1.w, color: Color(0xFFBFBFBF), margin: EdgeInsets.symmetric(horizontal: 8.w), ), Text( 'Daily updates, Stay tuned!', style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w400, color: Color(0xFF616161), ), ), ], ), SizedBox(height: 10.w), Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.white.withValues(alpha: .6), borderRadius: BorderRadius.circular(14.w), ), child: Row( children: [ KtNetworkImage( imageUrl: video.imageUrl ?? '', width: 108.w, height: 144.w, borderRadius: BorderRadius.circular(12.w), ), SizedBox(width: 12.w), SizedBox( width: 204.w, height: 144.w, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( video.name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w500, color: Color(0xFF1E1E20), ), ), SizedBox(height: 10.w), Text( video.description ?? '', maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10.sp, fontWeight: FontWeight.w400, color: Color(0xFF5E5E5E), ), ), Container( margin: EdgeInsets.symmetric( vertical: 11.w, ), height: 1.w, color: Color( 0xFFE8E4BD, ).withValues(alpha: .7), ), Row( children: [ Container( padding: EdgeInsets.symmetric( horizontal: 14.w, vertical: 7.w, ), decoration: BoxDecoration( color: Color(0xFF1E1E20), borderRadius: BorderRadius.circular( 100, ), ), child: Row( children: [ Image.asset( 'ic_top_play.png'.ktIcon, width: 16.w, ), SizedBox(width: 4.w), Text( 'Play', style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w500, color: Color(0xFFA7F62F), ), ), ], ), ), const Spacer(), Text( video.category?.first ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w400, color: Color(0xFF79C900), ), ), ], ), ], ), ), ], ), ), ], ), ), ); } return GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': video.shortPlayId, 'imageUrl': video.imageUrl ?? '', }, ), child: Container( width: ScreenUtil().screenWidth - 30.w, padding: EdgeInsets.symmetric(horizontal: 10.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(14.w), ), child: Row( children: [ KtNetworkImage( imageUrl: video.imageUrl ?? '', width: 108.w, height: 144.w, borderRadius: BorderRadius.circular(12.w), ), SizedBox(width: 12.w), SizedBox( width: 204.w, height: 144.w, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( video.name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w500, color: Color(0xFF1E1E20), ), ), SizedBox(height: 10.w), Text( video.description ?? '', maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10.sp, fontWeight: FontWeight.w400, color: Color(0xFF5E5E5E), ), ), Container( margin: EdgeInsets.symmetric(vertical: 11.w), height: 1.w, color: Color(0xFFE8E4BD).withValues(alpha: .7), ), Row( children: [ Container( padding: EdgeInsets.symmetric( horizontal: 14.w, vertical: 7.w, ), decoration: BoxDecoration( color: Color(0xFF1E1E20), borderRadius: BorderRadius.circular(100), ), child: Row( children: [ Image.asset( 'ic_top_play.png'.ktIcon, width: 16.w, ), SizedBox(width: 4.w), Text( 'Play', style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w500, color: Color(0xFFA7F62F), ), ), ], ), ), const Spacer(), Text( video.category?.first ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w400, color: Color(0xFF79C900), ), ), ], ), ], ), ), ], ), ), ); }, separatorBuilder: (_, __) => SizedBox(height: 10.w), ); }, ); } Widget categoryVideoView(int index) { return GetBuilder( id: 'category-list', key: ValueKey('category-$index'), builder: (ctrl) { if (state.categoryLoadStatus == KtLoadStatusType.loadNoData) { return KtStatusWidget( type: KtErrorStatusType.nothingYet, onPressed: logic.getCategoryVideoList, ); } return GridView.builder( padding: EdgeInsets.only(bottom: 16.w), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: 7.w, crossAxisSpacing: 7.w, childAspectRatio: 169 / 238, ), itemCount: state.categoryVideoList.length, itemBuilder: (BuildContext context, int index) { KtShortVideoBean video = state.categoryVideoList[index]; return GestureDetector( onTap: () => Get.toNamed( KtRoutes.shortVideo, arguments: { 'shortPlayId': video.shortPlayId, 'imageUrl': video.imageUrl ?? '', }, ), child: Container( width: 169.w, height: 219.w, padding: EdgeInsets.fromLTRB(8.w, 8.w, 8.w, 0.w), decoration: BoxDecoration( color: Color(0xFFF5F5F5), borderRadius: BorderRadius.circular(14.w), ), child: Column( children: [ Stack( clipBehavior: Clip.none, children: [ Container( width: 153.w, height: 203.w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.w), ), child: KtNetworkImage( imageUrl: video.imageUrl ?? '', borderRadius: BorderRadius.circular(6.w), ), ), Positioned( bottom: 5.w, right: 5.w, child: Image.asset( 'ic_rise_play.png'.ktIcon, width: 30.w, ), ), ], ), SizedBox(height: 5.w), SizedBox( width: 151.w, child: Center( child: Text( video.name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 12.sp, color: Color(0xFF616161), fontWeight: FontWeight.w400, ), ), ), ), ], ), ), ); }, ); }, ); } @override bool get wantKeepAlive => true; @override void initState() { super.initState(); tabCtrl = TabController(length: 3, vsync: this); } @override void dispose() { tabCtrl.dispose(); categoryTabCtrl?.dispose(); super.dispose(); } }