Files
huangguo_android/lib/hj_page/cartoon/cartoon_recommend_page.dart
T
2026-09-15 15:44:13 +07:00

103 lines
3.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/hj_model/cartoon_media_info.dart';
import 'package:hgdj/hj_utils/const.dart';
import 'package:hgdj/routers/jump_router.dart';
import 'package:hgdj/tools_base/loading/loading_center_widget.dart';
import 'package:hgdj/tools_base/refresh/pull_refresh.dart';
import 'package:hgdj/tools_base/unique_tag_mixin.dart';
import '../../hj_model/video_model.dart';
import '../home/home_cell_style/video_simple_cell.dart';
import 'acg_widget_item.dart';
import 'cartoon_recommend_logic.dart';
class CartoonRecommendPage extends StatefulWidget {
final String? mediaId;
final String? videoTagId; //视频(SP)推荐按当前视频 tag 拉同类
final EdgeInsetsGeometry? padding;
final Function()? tapAction;
final MediaStyle mediaStyle; //推荐类型:Video(真人视频) / Cartoon(动漫) / Comics(漫画)
final int crossAxisCount; //网格列数
final double childAspectRatio; //网格宽高比
final Function(VideoModel model)? onVideoTap; //视频 cell 点击:不传则走默认 push
final Function(CartoonMediaInfo model)? onAcgTap; //acg cell 点击:不传则走默认 push
const CartoonRecommendPage({
super.key,
this.mediaId,
this.tapAction,
this.padding = const EdgeInsets.only(left: 16, right: 16, top: 10),
this.mediaStyle = MediaStyle.Comics,
this.videoTagId,
this.crossAxisCount = 3,
this.childAspectRatio = 111 / 188,
this.onVideoTap,
this.onAcgTap,
});
@override
State<CartoonRecommendPage> createState() => _CartoonRecommendPageState();
}
class _CartoonRecommendPageState extends State<CartoonRecommendPage>
with UniqueTagMixin {
@override
Widget build(BuildContext context) {
return GetBuilder<CartoonRecommendLogic>(
tag: uniqueTag,
init: CartoonRecommendLogic(
mediaId: widget.mediaId,
mediaStyle: widget.mediaStyle,
videoTagId: widget.videoTagId,
),
builder: (logic) {
if (logic.isLoading) return LoadingCenterWidget();
if (logic.isEmptyData)
return CErrorWidget(retryOnTap: () => logic.loadData());
final list = logic.dataList!;
return pullYsRefresh(
onInit: (ctr) => logic.refreshCtr = ctr,
onLoading: (ctr) => logic.loadData(isRefresh: false),
enablePullDown: false,
child: GridView.builder(
physics: const ClampingScrollPhysics(),
padding: widget.padding,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: widget.crossAxisCount,
mainAxisSpacing: 12,
crossAxisSpacing: 6,
childAspectRatio: widget.childAspectRatio,
),
itemCount: list.length,
itemBuilder: (_, index) => widget.mediaStyle == MediaStyle.Video
? _videoCell(list[index])
: _acgCell(list[index]),
),
);
},
);
}
// 视频推荐 cell:不传 onVideoTap 走 cell 默认 push,详情页传入则当前页切播放源
Widget _videoCell(VideoModel model) {
return VideoSimpleCell(
videoModel: model,
onTap: widget.onVideoTap == null ? null : () => widget.onVideoTap!(model),
);
}
// 漫画/动漫推荐 cell:不传 onAcgTap 时默认跳详情页
Widget _acgCell(CartoonMediaInfo model) {
return AcgItemWidget(
info: model,
tapCallback: widget.onAcgTap == null
? () {
widget.tapAction?.call();
pushToCartoonPage(model);
}
: () => widget.onAcgTap!(model),
);
}
}