import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:hgdj/assets_tool/images.dart'; import 'package:hgdj/hj_model/acg/comic_chapters_model.dart'; import 'package:hgdj/hj_page/live/live_widget.dart'; import 'package:hgdj/hj_utils/screen.dart'; import 'package:hgdj/tools_base/widget/sheet_handle_bar.dart'; import 'package:hgdj/tools_base/widget/stagger_in_item.dart'; import '../../assets_tool/app_colors.dart'; import '../../hj_utils/widget_util.dart'; import 'widget/free_badge.dart'; //有声小说 选择子集 class AudioPlayerBottomSheet extends StatefulWidget { final String title; final List allAudiobooks; final Function(int)? indexHandler; final int? currentPlayIndex; final String? unit; //子集单位(章/集...),与详情子集 title 格式统一 final bool hasPermission; //整本是否已解锁:false 时前 N 集显示「免费」角标 AudioPlayerBottomSheet( this.title, { super.key, required this.allAudiobooks, this.indexHandler, this.currentPlayIndex, this.unit, this.hasPermission = false, }); @override State createState() => _AudioPlayerBottomSheetState(); } class _AudioPlayerBottomSheetState extends State { int sortType = 1; //0-降序,1-升序 @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 13), constraints: BoxConstraints(maxHeight: Get.height / 2), decoration: const BoxDecoration( color: AppColors.primaryColor, borderRadius: BorderRadius.vertical(top: Radius.circular(18)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Center(child: SheetHandleBar(color: Color(0xff989898))), 18.sizeBoxH, Row( children: [ Text( widget.title, style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500, ), ), Spacer(), InkWell( enableFeedback: false, onTap: () => setState(() => sortType = sortType == 1 ? 0 : 1), child: Row( children: [ AnimatedRotation( turns: sortType == 1 ? 0 : 0.5, duration: const Duration(milliseconds: 250), curve: Curves.easeOutCubic, child: Image.asset('text_play_sort.png'.acgImgPath, width: 18), ), 4.sizeBoxW, Text( sortType == 1 ? '正序' : '倒序', style: textStyle(12, Colors.white.withValues(alpha: .45), FontWeight.w400), ), ], ), ) ], ), 18.sizeBoxH, Expanded( child: ListView.separated( key: ValueKey(sortType), // 切换正/倒序时 key 变化→列表重建→item 重新错峰入场 separatorBuilder: (context, index) => Divider( height: 0.5, color: Colors.white.withValues(alpha: .05), ), itemCount: widget.allAudiobooks.length, itemBuilder: (context, index) { final realIndex = getRealIndex(index); final model = widget.allAudiobooks[realIndex]; final select = widget.currentPlayIndex == realIndex; return StaggerInItem( index: index, child: InkWell( enableFeedback: false, onTap: () { Get.back(result: realIndex); widget.indexHandler?.call(realIndex); }, child: Container( padding: const EdgeInsets.only(bottom: 6), child: Column( children: [ 16.sizeBoxH, Row( children: [ if (select) ...[ AudioWaveView(), 8.sizeBoxW, ], Expanded( child: Text( //与详情/抽屉子集 title 格式一致:第X章 '第${model.episodeNumber ?? 1}${widget.unit ?? ''}', style: TextStyle( color: select ? AppColors.actionRed : Colors.white .withValues(alpha: .9), fontSize: 14, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), //无任何权限时,前 N 集免费展示「免费」角标 if (widget.hasPermission == false && model.inFreeEpisode) ...[ 8.sizeBoxW, const FreeBadge(), ], 8.sizeBoxW, const Icon( Icons.navigate_next, size: 18, color: Color(0xffDCDCDC), ) ], ), 16.sizeBoxH, ], )), )); }, ), ) ], ), ); } int getRealIndex(int index) { return (sortType == 1) ? index : widget.allAudiobooks.length - index - 1; } }