import 'package:flutter/material.dart'; import 'package:skywood/main/lib_file.dart'; import 'package:skywood/pages/like/pages/collection_page.dart'; import 'package:skywood/pages/like/pages/play_log_page.dart'; import 'package:skywood/pages/like/widget/like_header.dart'; import 'package:skywood/pages/widgets/common_bg_page.dart'; import 'package:skywood/pages/widgets/pixel_widgets.dart'; import 'package:skywood/utils/extend/app_keep_alive.dart'; class LikePage extends StatefulWidget { const LikePage({super.key}); @override State createState() { return _MainRootState(); } } class _MainRootState extends State { int _tabIndex = 0; final _pageController = PageController(initialPage: 0); final List _collectionTitles = const [ 'Undercover Play', "Don't Cross Me", 'Two Worlds Apart', 'Rekindled Scorn', 'My Revenge is You', "Mr. Gu's Sweet Weakness", ]; @override Widget build(BuildContext context) { return CommonBgPage( child: SafeArea( bottom: false, child: Padding( padding: EdgeInsets.only(left: 15.w, right: 15.w, top: 20.h, bottom: 10.h+50.h), child: Stack( children: [ HelpImg.asset(ConstImg.likeBg, width: AppScreen.screenWidth - 30.w, height: 700.h, fit: BoxFit.fill, ), Padding( padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h), child: Column( children: [ Padding( padding: const EdgeInsets.only(left: 10, top: 10), child: LikeHeader( onSelectedIndex: (index) { _pageController.jumpToPage(index); }, ), ), // 主页面 Expanded( child: PageView( controller: _pageController, children: [ AppKeepAlive(child: CollectionPage()), AppKeepAlive(child: PlayLogPage()) ], ), ) ], ), ), ], ), )), ); } Widget _buildTabs() { return Row( children: [ Expanded( child: _LibraryTab( title: 'My Collection', selected: _tabIndex == 0, onTap: () => setState(() => _tabIndex = 0), ), ), SizedBox(width: 8.w), Expanded( child: _LibraryTab( title: 'Play Log', selected: _tabIndex == 1, onTap: () => setState(() => _tabIndex = 1), ), ), ], ); } Widget _buildCollection() { return GridView.builder( key: const ValueKey('collection'), padding: EdgeInsets.only(top: 2.h, bottom: 120.h), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 10.h, crossAxisSpacing: 7.w, childAspectRatio: 100 / 174, ), itemCount: _collectionTitles.length, itemBuilder: (context, index) { return _CollectionCard(title: _collectionTitles[index]); }, ); } Widget _buildPlayLog() { return ListView( key: const ValueKey('play-log'), padding: EdgeInsets.only(bottom: 120.h), children: [ _ContinueCard(), SizedBox(height: 18.h), Text( 'Watch History', style: TextStyle( color: const Color(0xFF1C1E1F), fontSize: 16.sp, fontWeight: FontWeight.w700, height: 1, ), ), SizedBox(height: 10.h), _HistoryItem(title: 'As A Mafia Boss, I Refuse To Be An Extra'), SizedBox(height: 10.h), _HistoryItem(title: 'Fatal Vengeance'), SizedBox(height: 10.h), _HistoryItem(title: "Don't Cross Me"), ], ); } } class _LibraryTab extends StatelessWidget { const _LibraryTab({ required this.title, required this.selected, required this.onTap, }); final String title; final bool selected; final VoidCallback onTap; @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Container( height: 45.h, alignment: Alignment.center, decoration: BoxDecoration( color: selected ? const Color(0xFF16ED1E) : const Color(0xFFF6F6F6), border: Border.all( color: selected ? CommonColor.black : const Color(0xFFD6D6D6), width: 1.5.w, ), boxShadow: selected ? const [ BoxShadow(color: Color(0xFF1C1E1F), offset: Offset(2, 2)), ] : null, ), child: Text( title, style: TextStyle( color: selected ? Colors.white : const Color(0xFFB2B2B2), fontSize: 14.sp, fontWeight: FontWeight.w900, height: 1, shadows: selected ? const [Shadow(color: Color(0xFF1C1E1F), offset: Offset(1, 1))] : null, ), ), ), ); } } class _CollectionCard extends StatelessWidget { const _CollectionCard({required this.title}); final String title; @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.fromLTRB(4.w, 8.h, 4.w, 6.h), decoration: BoxDecoration( color: const Color(0xFFF4FFB6), border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w), boxShadow: const [ BoxShadow(color: Color(0xFF653CFA), offset: Offset(3, 3)), ], ), child: Column( children: [ Row( children: List.generate(4, (index) { return Container( width: 11.w, height: 6.h, margin: EdgeInsets.only(right: 5.w), decoration: BoxDecoration( color: index == 3 ? const Color(0xFFEAEAEA) : const Color(0xFF96FE9B), border: Border.all( color: const Color(0xFF1C1E1F), width: 0.8.w, ), ), ); }), ), SizedBox(height: 8.h), const Expanded(child: PosterImage()), SizedBox(height: 8.h), Text( title, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( color: const Color(0xFF1C1E1F), fontSize: 13.sp, fontWeight: FontWeight.w500, height: 1, ), ), ], ), ); } } class _ContinueCard extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: 140.h, padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: const Color(0xFFEAE6FF), border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w), ), child: Row( children: [ const PosterImage(width: 90, height: 120, borderRadius: 2), SizedBox(width: 10.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Mogul And His Runaway Bride', maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle( color: const Color(0xFF1B1926), fontSize: 14.sp, fontWeight: FontWeight.w600, height: 1.25, ), ), SizedBox(height: 18.h), Text( 'Chapter 10 / 28', style: TextStyle( color: CommonColor.primacyColor, fontSize: 11.sp, height: 1, ), ), SizedBox(height: 6.h), _ProgressLine(value: 0.46), const Spacer(), const PixelButton( label: 'Continue Watch', width: 145, height: 29, ), ], ), ), ], ), ); } } class _HistoryItem extends StatelessWidget { const _HistoryItem({required this.title}); final String title; @override Widget build(BuildContext context) { return Container( height: 100.h, padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 6.h), decoration: BoxDecoration( color: const Color(0xFFEAE6FF), border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w), ), child: Row( children: [ const PosterImage(width: 66, height: 88, borderRadius: 2), SizedBox(width: 10.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( title, maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle( color: CommonColor.black, fontSize: 13.sp, fontWeight: FontWeight.w600, height: 1.2, ), ), Text( 'EP.40/85', style: TextStyle( color: CommonColor.primacyColor, fontSize: 11.sp, height: 1, ), ), _ProgressLine(value: 0.46), ], ), ), ], ), ); } } class _ProgressLine extends StatelessWidget { const _ProgressLine({required this.value}); final double value; @override Widget build(BuildContext context) { return Row( children: [ Expanded( child: Container( height: 6.h, decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.7), border: Border.all(color: const Color(0xFF1C1E1F), width: 0.5.w), borderRadius: BorderRadius.circular(10.r), ), alignment: Alignment.centerLeft, child: FractionallySizedBox( widthFactor: value, child: Container( decoration: BoxDecoration( color: const Color(0xFF00EE02), borderRadius: BorderRadius.circular(10.r), ), ), ), ), ), SizedBox(width: 4.w), Text('46%', style: TextStyle(fontSize: 10.sp, height: 1)), ], ); } }