109 lines
3.8 KiB
Dart
109 lines
3.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:hgdj/assets_tool/images.dart';
|
|
|
|
import '../../hj_model/splash/ads_model.dart';
|
|
import '../../hj_utils/screen.dart';
|
|
import '../../tools_base/banner/ads_banner_widget.dart';
|
|
import '../../tools_base/banner/ads_item.dart';
|
|
|
|
class AppCenterDialog extends StatefulWidget {
|
|
final List<AdsInfoModel>? appList;
|
|
final List<AdsInfoModel>? adsList;
|
|
final VoidCallback? callback;
|
|
|
|
const AppCenterDialog({super.key, this.appList, this.callback, this.adsList});
|
|
|
|
@override
|
|
State<AppCenterDialog> createState() => _AppCenterDialogState();
|
|
}
|
|
|
|
class _AppCenterDialogState extends State<AppCenterDialog> {
|
|
bool _showClose = false;
|
|
|
|
List<AdsInfoModel> get _appList => widget.appList ?? [];
|
|
|
|
/// 网格高度上限 = 4 行 + 底部留白,超出滚动。数字跟下面 gridDelegate 对应,改一处要同步。
|
|
/// 别用「首帧 shrinkWrap 量高度、次帧再改成固定高」那套——两帧布局不同,弹窗又居中,打开瞬间会跳
|
|
double get _maxGridHeight {
|
|
final itemWidth = (Get.width - 32 * 2 - 12 * 3) / 4;
|
|
return itemWidth * 93 / 68 * 4 + 16 * 3 + 25;
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
// 1 秒后再显示关闭按钮,防误触
|
|
Future.delayed(const Duration(milliseconds: 1000), () {
|
|
if (mounted) setState(() => _showClose = true);
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Material(
|
|
color: Colors.black.withValues(alpha: 0.6),
|
|
child: Center(
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 32),
|
|
alignment: Alignment.center,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
if (widget.adsList?.isNotEmpty == true)
|
|
Container(
|
|
margin: const EdgeInsets.only(bottom: 24),
|
|
child: AdsBannerWidget(
|
|
widget.adsList,
|
|
width: 329,
|
|
height: 88,
|
|
autoPlayMs: 5000,
|
|
),
|
|
),
|
|
//Flexible 兜住矮屏:内容再多也不会顶破屏幕
|
|
Flexible(
|
|
child: ConstrainedBox(
|
|
constraints: BoxConstraints(maxHeight: _maxGridHeight),
|
|
child: GridView.builder(
|
|
padding: const EdgeInsets.only(bottom: 25),
|
|
shrinkWrap: true, //不足 4 行时按内容收,不留空
|
|
physics: const ClampingScrollPhysics(),
|
|
itemCount: _appList.length,
|
|
gridDelegate:
|
|
const SliverGridDelegateWithFixedCrossAxisCount(
|
|
crossAxisCount: 4,
|
|
crossAxisSpacing: 12,
|
|
mainAxisSpacing: 16,
|
|
childAspectRatio: 68 / 93,
|
|
),
|
|
itemBuilder: (context, index) {
|
|
return AdsItem(
|
|
adInfo: _appList[index],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
32.sizeBoxH,
|
|
//一直挂在树上只切显隐:等 _showClose 才 build 的话,asset 解码前图高是 0,
|
|
//会先塌一下再弹回来,居中布局跟着抖
|
|
Opacity(
|
|
opacity: _showClose ? 1 : 0,
|
|
child: IgnorePointer(
|
|
ignoring: !_showClose,
|
|
child: GestureDetector(
|
|
onTap: () => Get.back(),
|
|
child: Image.asset("close_button.png".commonImgPath,
|
|
width: 32, height: 32),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|