初始化

This commit is contained in:
谢宇宁
2026-09-15 15:44:13 +07:00
commit a23ba685e9
1065 changed files with 101122 additions and 0 deletions
+108
View File
@@ -0,0 +1,108 @@
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),
),
),
),
],
),
),
),
);
}
}