Files
hgmj_android/lib/tools_base/banner/ads_item.dart
T
2026-10-08 20:10:40 +07:00

157 lines
4.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jydj/assets_tool/images.dart';
import 'package:jydj/hj_utils/api_service/common_service.dart';
import 'package:jydj/hj_utils/screen.dart';
import '../../hj_model/splash/ads_model.dart';
import '../../routers/jump_router.dart';
import '../widget/net_image_widget.dart';
enum AdShowType {
img, //纯图片
hor, //水平:左图标题 + 右下载按钮
vImgText, //图文:上图下文
splash, //启动全屏图
}
/// 广告项:按 [AdShowType] 出不同样式(不传是上图下标题的九宫格项);点击按链接跳转并上报
class AdsItem extends StatefulWidget {
final AdsInfoModel adInfo;
final AdShowType? showType;
final double? aspectRatio;
final double borderRadius; //纯图样式的圆角
final Widget? child; //自定义子视图(IM 广告用)
final VoidCallback? onTap; //点击附加回调(IM 广告已读上报用)
const AdsItem({
super.key,
required this.adInfo,
this.showType,
this.aspectRatio,
this.borderRadius = 12,
this.child,
this.onTap,
});
@override
State<AdsItem> createState() => _AdsItemState();
}
class _AdsItemState extends State<AdsItem> {
AdsInfoModel get adInfo => widget.adInfo;
@override
Widget build(BuildContext context) {
return InkWell(
enableFeedback: false,
onTap: _onTap,
child: widget.child ??
switch (widget.showType) {
AdShowType.img => _image(),
AdShowType.hor => _hor(),
AdShowType.vImgText => _imageText(),
AdShowType.splash => _splash(),
null => _normal(),
},
);
}
void _onTap() {
pushToPageByLink(adInfo.href);
CommonService.adsClick(adInfo.id);
widget.onTap?.call();
}
//启动全屏图:封面铺满 + 兜底背景图
Widget _splash() {
return NetworkImageLoader(
imageUrl: adInfo.cover ?? '',
width: Get.width,
height: Get.height,
fit: BoxFit.cover,
placeHolderWidget: Image.asset('ic_splash_bg.webp'.launchPath, fit: BoxFit.cover, width: Get.width, height: Get.height),
);
}
//默认样式:上图下标题(九宫格项)
Widget _normal() {
return Column(
children: [
AspectRatio(
aspectRatio: widget.aspectRatio ?? 1,
child: NetworkImageLoader(imageUrl: adInfo.cover ?? '', borderRadius: 12),
),
const Spacer(),
Text(
adInfo.title?.trim() ?? '',
maxLines: 1,
style: const TextStyle(color: Color(0xffFAFAFA), fontSize: 11),
),
const Spacer(),
],
);
}
//图文样式:上图下文
Widget _imageText() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio: 72 / 20,
child: NetworkImageLoader(
borderRadius: 4,
imageUrl: adInfo.cover ?? '',
width: double.infinity,
height: double.infinity,
fit: BoxFit.fill,
),
),
10.sizeBoxH,
Text(
adInfo.title ?? '',
style: const TextStyle(color: Color(0xffdddfdf), fontWeight: FontWeight.w300, fontSize: 12),
),
],
);
}
//纯图样式:可选宽高比
Widget _image() {
final image = NetworkImageLoader(
imageUrl: adInfo.cover ?? '',
borderRadius: widget.borderRadius,
fit: BoxFit.fill,
);
final ratio = widget.aspectRatio;
return ratio == null ? image : AspectRatio(aspectRatio: ratio, child: image);
}
//水平样式:左图 + 标题,右「立即下载」按钮
Widget _hor() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
//图片自己切 10 的圆角
NetworkImageLoader(imageUrl: adInfo.cover ?? '', borderRadius: 10, width: 50, height: 50),
10.sizeBoxW,
Text(
adInfo.title ?? '',
style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w300, fontSize: 12),
),
],
),
Container(
width: 72,
height: 28,
decoration: BoxDecoration(color: const Color(0xff3476FF), borderRadius: BorderRadius.circular(14)),
child: const Center(child: Text('立即下载', style: TextStyle(color: Colors.white, fontSize: 12))),
),
],
);
}
}