初始化
This commit is contained in:
@@ -0,0 +1,287 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgdj/assets_tool/images.dart';
|
||||
import 'package:hgdj/hj_page/live/live_item_widget.dart';
|
||||
import 'package:hgdj/hj_utils/screen.dart';
|
||||
import 'package:hgdj/tools_base/banner/ads_grid_view_widget.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/widget/card_swiper/src/swiper.dart';
|
||||
|
||||
import 'live_model.dart';
|
||||
import 'live_sub_logic.dart';
|
||||
|
||||
//直播子列表页面
|
||||
class LiveSubPage extends StatefulWidget {
|
||||
final LiveModule? tagData;
|
||||
|
||||
const LiveSubPage({super.key, this.tagData});
|
||||
|
||||
@override
|
||||
State<LiveSubPage> createState() => _LiveSubPageState();
|
||||
}
|
||||
|
||||
class _LiveSubPageState extends State<LiveSubPage> {
|
||||
String get _tag => widget.tagData?.id ?? '';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('live_main_bg.webp'.livePath), fit: BoxFit.fill),
|
||||
),
|
||||
child: GetBuilder<LiveSubLogic>(
|
||||
init: LiveSubLogic(tagData: widget.tagData),
|
||||
tag: _tag,
|
||||
builder: (logic) => pullYsRefresh(
|
||||
enablePullUp: !logic.isRecom,
|
||||
onInit: (c) => logic.controller = c,
|
||||
onRefresh: (c) => logic.loadData(),
|
||||
onLoading: (c) => logic.loadMoreData(),
|
||||
child: _buildContent(logic),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildContent(LiveSubLogic logic) {
|
||||
//列表样式
|
||||
if (!logic.isRecom) {
|
||||
return CustomScrollView(
|
||||
slivers: [_buildAdBanner(), _buildAnchorGrid(logic)]);
|
||||
}
|
||||
//推荐样式
|
||||
if (logic.liveMainModel?.recom == null) return const LoadingCenterWidget();
|
||||
if (logic.liveMainModel?.recom?.isEmpty == true) {
|
||||
return CErrorWidget(retryOnTap: () => logic.loadData());
|
||||
}
|
||||
return CustomScrollView(slivers: _buildRecomItems(logic));
|
||||
}
|
||||
|
||||
//广告 banner
|
||||
Widget _buildAdBanner() {
|
||||
return SliverToBoxAdapter(
|
||||
child: AdsGridViewWidget(
|
||||
35,
|
||||
accordingAdsType: true,
|
||||
padding: const EdgeInsets.fromLTRB(16, 15, 16, 15),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//国家/标签主播列表
|
||||
Widget _buildAnchorGrid(LiveSubLogic logic) {
|
||||
if (logic.loading) {
|
||||
return const SliverToBoxAdapter(
|
||||
child: SizedBox(height: 200, child: LoadingCenterWidget()));
|
||||
}
|
||||
if (logic.liveList.isEmpty) {
|
||||
return SliverToBoxAdapter(
|
||||
child: CErrorWidget(retryOnTap: () => logic.loadData()));
|
||||
}
|
||||
return SliverPadding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
sliver: SliverGrid(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 7,
|
||||
childAspectRatio: 168 / 105,
|
||||
),
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(_, index) =>
|
||||
LiveItemWidget(showType: 5, anchor: logic.liveList[index]),
|
||||
childCount: logic.liveList.length,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//推荐页各区块(首块额外叠充值入口)
|
||||
List<Widget> _buildRecomItems(LiveSubLogic logic) {
|
||||
final recomList = logic.liveMainModel?.recom ?? [];
|
||||
return List.generate(recomList.length, (i) {
|
||||
Widget section = _buildRecomSection(recomList[i]);
|
||||
if (i == 0) section = _wrapFirstSection(logic, section);
|
||||
return SliverToBoxAdapter(child: section);
|
||||
});
|
||||
}
|
||||
|
||||
//按 recoShowType 分发区块样式
|
||||
Widget _buildRecomSection(LiveRecom recom) {
|
||||
switch (recom.recoShowType) {
|
||||
case 'nine_grid':
|
||||
return _buildGridSection(recom,
|
||||
bg: 'live_section_bg_1.webp',
|
||||
title: 'nine_grid_bg.webp',
|
||||
titleHeight: 45,
|
||||
crossAxisCount: 3,
|
||||
mainSpacing: 12,
|
||||
crossSpacing: 5,
|
||||
aspectRatio: 1,
|
||||
showType: 0);
|
||||
case 'six_round':
|
||||
return _buildGridSection(recom,
|
||||
bg: 'live_section_bg_2.webp',
|
||||
title: 'six_round_bg.webp',
|
||||
titleHeight: 45,
|
||||
crossAxisCount: 2,
|
||||
mainSpacing: 0,
|
||||
crossSpacing: 6,
|
||||
aspectRatio: 168 / 85,
|
||||
showType: 1,
|
||||
bottomSpace: 10);
|
||||
case 'four_grid':
|
||||
return _buildGridSection(recom,
|
||||
bg: 'live_section_bg_3.webp',
|
||||
title: 'four_grid_bg.webp',
|
||||
titleHeight: 45,
|
||||
crossAxisCount: 2,
|
||||
mainSpacing: 12,
|
||||
crossSpacing: 7,
|
||||
aspectRatio: 1,
|
||||
showType: 2,
|
||||
bottomSpace: 18);
|
||||
case 'six_grid':
|
||||
return _buildGridSection(recom,
|
||||
bg: 'live_section_bg_4.webp',
|
||||
title: 'six_grid_bg.webp',
|
||||
titleHeight: 36,
|
||||
crossAxisCount: 3,
|
||||
mainSpacing: 12,
|
||||
crossSpacing: 5,
|
||||
aspectRatio: 1,
|
||||
showType: 3);
|
||||
case 'horizontal_slide':
|
||||
return _buildHorizontalSlide(recom);
|
||||
case 'list':
|
||||
return _buildRecomList(recom.anchors);
|
||||
default:
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
|
||||
//首个区块叠加充值入口
|
||||
Widget _wrapFirstSection(LiveSubLogic logic, Widget section) {
|
||||
return Stack(
|
||||
alignment: Alignment.topCenter,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [178.sizeBoxH, section, 10.sizeBoxH]),
|
||||
Positioned(
|
||||
top: 20,
|
||||
child: GestureDetector(
|
||||
onTap: () => logic.onChargeAction(),
|
||||
child: Image.asset('live_charge.webp'.livePath, height: 148),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
//宫格类区块(九宫格/六圆形/四宫格/六宫格 共用)
|
||||
Widget _buildGridSection(
|
||||
LiveRecom? recom, {
|
||||
required String bg,
|
||||
required String title,
|
||||
required double titleHeight,
|
||||
required int crossAxisCount,
|
||||
required double mainSpacing,
|
||||
required double crossSpacing,
|
||||
required double aspectRatio,
|
||||
required int showType,
|
||||
double bottomSpace = 0,
|
||||
}) {
|
||||
final anchors = recom?.anchors;
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
image:
|
||||
DecorationImage(image: AssetImage(bg.livePath), fit: BoxFit.fill),
|
||||
),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 34),
|
||||
child: Column(
|
||||
children: [
|
||||
18.sizeBoxH,
|
||||
Image.asset(title.livePath, height: titleHeight),
|
||||
18.sizeBoxH,
|
||||
GridView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: crossAxisCount,
|
||||
mainAxisSpacing: mainSpacing,
|
||||
crossAxisSpacing: crossSpacing,
|
||||
childAspectRatio: aspectRatio,
|
||||
),
|
||||
itemCount: anchors?.length ?? 0,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
//index 仅 showType==2 用于渲染前三角标,其余样式忽略
|
||||
itemBuilder: (_, index) => LiveItemWidget(
|
||||
showType: showType, anchor: anchors?[index], index: index),
|
||||
),
|
||||
if (bottomSpace > 0) bottomSpace.sizeBoxH,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//横向滑动
|
||||
Widget _buildHorizontalSlide(LiveRecom? recom) {
|
||||
final anchors = recom?.anchors;
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
const Color(0xffFF8E8E).withValues(alpha: 0),
|
||||
const Color(0xffFF8E8E).withValues(alpha: .2),
|
||||
const Color(0xffFF8E8E).withValues(alpha: 0),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
18.sizeBoxH,
|
||||
Container(
|
||||
height: 175,
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Swiper(
|
||||
autoplay: true,
|
||||
autoplayDelay: 5000,
|
||||
viewportFraction: 0.8,
|
||||
scale: 0.93,
|
||||
itemCount: anchors?.length ?? 0,
|
||||
itemBuilder: (c, index) =>
|
||||
LiveItemWidget(showType: 4, anchor: anchors?[index]),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//推荐无限下滑列表
|
||||
Widget _buildRecomList(List<LiveAnchor>? anchors) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 28),
|
||||
child: GridView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 5,
|
||||
childAspectRatio: 168 / 105,
|
||||
),
|
||||
itemCount: anchors?.length ?? 0,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (_, index) =>
|
||||
LiveItemWidget(showType: 5, anchor: anchors?[index]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user