83 lines
3.2 KiB
Dart
83 lines
3.2 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:get/get.dart';
|
||
import 'package:hgdj/hj_page/drama/drama_feed_logic.dart';
|
||
import 'package:hgdj/hj_page/drama/view/drama_video_player.dart';
|
||
import 'package:hgdj/tools_base/loading/loading_center_widget.dart';
|
||
import 'package:hgdj/tools_base/unique_tag_mixin.dart';
|
||
|
||
/// AI短剧信息流页:竖划一部换一部,每条播该剧第 1 集
|
||
class DramaFeedPage extends StatefulWidget {
|
||
final TabController? superTabCtr;
|
||
final int? tabIndex;
|
||
|
||
const DramaFeedPage({super.key, this.superTabCtr, this.tabIndex});
|
||
|
||
@override
|
||
State<DramaFeedPage> createState() => _DramaFeedPageState();
|
||
}
|
||
|
||
class _DramaFeedPageState extends State<DramaFeedPage> with UniqueTagMixin {
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return GetBuilder<DramaFeedLogic>(
|
||
tag: uniqueTag, // 多 tab 并存,按实例隔离
|
||
init: DramaFeedLogic(
|
||
superTabCtr: widget.superTabCtr, tabIndex: widget.tabIndex),
|
||
builder: (logic) {
|
||
final Widget content;
|
||
if (!logic.isFirstLoaded) {
|
||
content = const LoadingCenterWidget();
|
||
} else if (logic.list?.isNotEmpty != true) {
|
||
content = CErrorWidget(retryOnTap: () => logic.loadData());
|
||
} else {
|
||
content = _buildFeed(logic);
|
||
}
|
||
return Material(color: Colors.transparent, child: content);
|
||
},
|
||
);
|
||
}
|
||
|
||
/// 信息流局部刷新:当前页变化时只 update([idFeed]),各 item 重算 isCurrentPage
|
||
Widget _buildFeed(DramaFeedLogic logic) {
|
||
return RefreshIndicator(
|
||
onRefresh: () => logic.loadData(),
|
||
child: GetBuilder<DramaFeedLogic>(
|
||
tag: uniqueTag,
|
||
id: DramaFeedLogic.idFeed,
|
||
// 上下滑动开始/结束 → 切换 isScrolling,各播放器据此隐藏/显示进度条
|
||
builder: (logic) => NotificationListener<ScrollNotification>(
|
||
onNotification: (n) {
|
||
if (n is ScrollStartNotification) {
|
||
logic.isScrolling.value = true;
|
||
} else if (n is ScrollEndNotification) {
|
||
logic.isScrolling.value = false;
|
||
}
|
||
return false;
|
||
},
|
||
child: PageView.builder(
|
||
onPageChanged: logic.onPageChanged,
|
||
physics: const ClampingScrollPhysics(),
|
||
controller: logic.pageCtr,
|
||
scrollDirection: Axis.vertical,
|
||
allowImplicitScrolling: true,
|
||
itemCount: logic.list?.length ?? 0,
|
||
itemBuilder: (context, index) {
|
||
final video = logic.list![index];
|
||
//推荐流不去重,同一部剧会反复下发,光用剧 id 会撞 key(PageView 直接抛 Duplicate keys);
|
||
//带上下标才唯一。也不能只用下标——下拉刷新后同一个位置换了别的剧,
|
||
//key 不变 PageView 就会复用 State,播放器不重建,播的还是上一部
|
||
return DramaVideoPlayer(
|
||
key: ValueKey('${video.dramaInfo?.id ?? ''}#$index'),
|
||
index: index,
|
||
isCurrentPage: logic.pageIndex == index,
|
||
videoInfo: video,
|
||
isScrolling: logic.isScrolling,
|
||
);
|
||
},
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|