logo和名称替换

This commit is contained in:
谢宇宁
2026-10-14 11:23:36 +07:00
parent 1cb514cd02
commit c5c04a7967
478 changed files with 8990 additions and 4948 deletions
+28 -18
View File
@@ -1,17 +1,17 @@
import 'package:hgmj/hj_model/list_base_model.dart';
import 'package:wydj/hj_model/list_base_model.dart';
import 'dart:async';
import 'package:get/get.dart';
import 'package:hgmj/hj_model/video_model.dart';
import 'package:hgmj/hj_page/live/live_service.dart';
import 'package:hgmj/hj_utils/date_time_util.dart';
import 'package:hgmj/tools_base/event_bus/event_bus_util.dart';
import 'package:hgmj/tools_base/event_bus/events.dart';
import 'package:hgmj/tools_base/toast.dart';
import 'package:hgmj/tools_base/global_store/store.dart';
import 'package:wydj/hj_model/video_model.dart';
import 'package:wydj/hj_page/live/live_service.dart';
import 'package:wydj/hj_utils/date_time_util.dart';
import 'package:wydj/tools_base/event_bus/event_bus_util.dart';
import 'package:wydj/tools_base/event_bus/events.dart';
import 'package:wydj/tools_base/toast.dart';
import 'package:wydj/tools_base/global_store/store.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:video_player/video_player.dart';
import 'package:hgmj/hj_utils/video_view_type.dart';
import 'package:wydj/hj_utils/video_view_type.dart';
import '../../alert/video/share_media_dialog.dart';
import '../mine/mine_vip/mine_charge_vip_page.dart';
@@ -39,7 +39,8 @@ class LiveDetailLogic extends GetxController {
bool isDispose = false;
//判断播放权限
bool get canWatchLive => DateTimeUtil.isExpireDate(globalStore.meInfo?.broadcastExpire);
bool get canWatchLive =>
DateTimeUtil.isExpireDate(globalStore.meInfo?.broadcastExpire);
LiveDetailLogic({this.anchor});
@@ -49,13 +50,15 @@ class LiveDetailLogic extends GetxController {
void onInit() {
super.onInit();
// 耳机/蓝牙断开、来电中断时暂停,防止外放泄露
_pauseVideoSub = eventBus.on<PauseVideoEvent>((_) => playerController?.pause());
_pauseVideoSub =
eventBus.on<PauseVideoEvent>((_) => playerController?.pause());
}
@override
void onReady() async {
super.onReady();
Future.wait([globalStore.updateUserInfo(), loadData(initVideo: false)]).then(
Future.wait([globalStore.updateUserInfo(), loadData(initVideo: false)])
.then(
(value) {
update(); //接口调用成功刷新一次直播状态
loadingUserInfo = false;
@@ -89,7 +92,8 @@ class LiveDetailLogic extends GetxController {
try {
await playerController?.initialize();
if (isRetry) confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地
if (isRetry)
confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地
playerController?.addListener(_listenerCallback);
if (isDispose) {
playerController?.pause();
@@ -124,7 +128,8 @@ class LiveDetailLogic extends GetxController {
//获取直播详情
Future loadData({bool initVideo = true}) async {
LiveAnchor? result = await LiveService.getLiveAnchorDetail(id: anchor?.id ?? '');
LiveAnchor? result =
await LiveService.getLiveAnchorDetail(id: anchor?.id ?? '');
controller?.refreshCompleted();
if (result != null) {
//不需要赋值图片url,因为图片随时在变,防止图片闪动
@@ -139,7 +144,8 @@ class LiveDetailLogic extends GetxController {
//直播推荐列表
loadrecommendAnchors({int pageNum = 1}) async {
ListBaseModel<LiveAnchor>? liveMainModels = await LiveService.getLiveAnchorRecom(
ListBaseModel<LiveAnchor>? liveMainModels =
await LiveService.getLiveAnchorRecom(
country: anchor?.country ?? '',
pageNumber: pageNum,
pageSize: 20,
@@ -148,13 +154,16 @@ class LiveDetailLogic extends GetxController {
if (liveMainModels != null) {
currentPage = pageNum;
if (currentPage == 1) recommendList.clear();
if (liveMainModels.list != null && liveMainModels.list?.isNotEmpty == true) {
if (liveMainModels.list != null &&
liveMainModels.list?.isNotEmpty == true) {
recommendList.addAll(liveMainModels.list ?? []);
}
}
controller?.refreshCompleted();
update(['recommend']);
liveMainModels?.hasNext == true ? controller?.loadComplete() : controller?.loadNoData();
liveMainModels?.hasNext == true
? controller?.loadComplete()
: controller?.loadNoData();
}
loadMoreData() => loadrecommendAnchors(pageNum: currentPage + 1);
@@ -195,6 +204,7 @@ class LiveDetailLogic extends GetxController {
onShareAction() {
VideoModel videoModel = VideoModel()..cover = anchor?.coverImg;
Get.dialog(ShareMediaDialog(videoModel: videoModel, needDecrypt: false), useSafeArea: false);
Get.dialog(ShareMediaDialog(videoModel: videoModel, needDecrypt: false),
useSafeArea: false);
}
}
+54 -27
View File
@@ -1,14 +1,14 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgmj/assets_tool/images.dart';
import 'package:hgmj/hj_page/live/live_item_widget.dart';
import 'package:hgmj/hj_page/live/live_model.dart';
import 'package:hgmj/hj_utils/screen.dart';
import 'package:hgmj/hj_utils/sliver_delegate.dart';
import 'package:hgmj/tools_base/banner/ads_grid_view.dart';
import 'package:hgmj/tools_base/loading/loading_center_widget.dart';
import 'package:hgmj/tools_base/refresh/pull_refresh.dart';
import 'package:hgmj/tools_base/widget/net_image_widget.dart';
import 'package:wydj/assets_tool/images.dart';
import 'package:wydj/hj_page/live/live_item_widget.dart';
import 'package:wydj/hj_page/live/live_model.dart';
import 'package:wydj/hj_utils/screen.dart';
import 'package:wydj/hj_utils/sliver_delegate.dart';
import 'package:wydj/tools_base/banner/ads_grid_view.dart';
import 'package:wydj/tools_base/loading/loading_center_widget.dart';
import 'package:wydj/tools_base/refresh/pull_refresh.dart';
import 'package:wydj/tools_base/widget/net_image_widget.dart';
import 'package:video_player/video_player.dart';
import '../video/video_full_page.dart';
@@ -54,7 +54,9 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
delegate: MySliverDelegate(
forceRefresh: true,
maxHeight: Get.width / (logic.aspectRatio ?? 1),
minHeight: logic.isVerticalVideo ? Get.width / (logic.aspectRatio ?? 1) : Get.height / 3 - 60,
minHeight: logic.isVerticalVideo
? Get.width / (logic.aspectRatio ?? 1)
: Get.height / 3 - 60,
child: ClipRRect(
//部分机型会超出比例,裁剪掉多余部分
child: Container(color: Colors.black, child: _buildPlayer()),
@@ -70,7 +72,10 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
padding: const EdgeInsets.fromLTRB(16, 18, 16, 12),
child: const Text(
'精彩推荐',
style: TextStyle(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w500),
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w500),
),
),
),
@@ -91,7 +96,8 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
children: [
if (logic.loadingUserInfo) ...[
//1.加载用户直播权益信息
AspectRatio(aspectRatio: logic.aspectRatio ?? 1, child: _buildCover(logic)),
AspectRatio(
aspectRatio: logic.aspectRatio ?? 1, child: _buildCover(logic)),
const LoadingCenterWidget(),
] else if (!logic.canWatchLive) ...[
//2.无权限
@@ -105,7 +111,9 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
tag: 'player',
child: AspectRatio(
aspectRatio: logic.aspectRatio ?? 1,
child: logic.initedVideoController ? VideoPlayer(logic.playerController!) : _buildCover(logic),
child: logic.initedVideoController
? VideoPlayer(logic.playerController!)
: _buildCover(logic),
),
),
if (logic.initedVideoController)
@@ -113,11 +121,15 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
right: 12,
bottom: 6,
child: GestureDetector(
onTap: () => Get.to(() => VideoFullPage(playCtr: logic.playerController!, showMenu: false)),
child: Image.asset("full_icon.png".videoPath, width: 26, height: 26),
onTap: () => Get.to(() => VideoFullPage(
playCtr: logic.playerController!, showMenu: false)),
child: Image.asset("full_icon.png".videoPath,
width: 26, height: 26),
),
),
Obx(() => Offstage(offstage: !logic.isLoading.value, child: const LoadingCenterWidget())),
Obx(() => Offstage(
offstage: !logic.isLoading.value,
child: const LoadingCenterWidget())),
],
],
),
@@ -139,10 +151,14 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
children: [
const Text(
'温馨提示',
style: TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500),
style: TextStyle(
fontSize: 14,
color: Colors.white,
fontWeight: FontWeight.w500),
),
12.sizeBoxH,
const Text('开通直播卡全站直播骚货免费观看', style: TextStyle(fontSize: 14, color: Colors.white)),
const Text('开通直播卡全站直播骚货免费观看',
style: TextStyle(fontSize: 14, color: Colors.white)),
18.sizeBoxH,
GestureDetector(
onTap: logic.onChargeAction,
@@ -155,8 +171,11 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
colors: [Color(0xffffe8be), Color(0xffe5b764)],
),
),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
child: const Text('立即开通直播卡', style: TextStyle(fontSize: 14, color: Color(0xFF7b0000))),
padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
child: const Text('立即开通直播卡',
style:
TextStyle(fontSize: 14, color: Color(0xFF7b0000))),
),
),
],
@@ -178,7 +197,8 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
Container(
color: Colors.black.withValues(alpha: .7),
alignment: Alignment.center,
child: const Text('当前主播离线,请前往观看其她热门主播喔~', style: TextStyle(fontSize: 14, color: Colors.white)),
child: const Text('当前主播离线,请前往观看其她热门主播喔~',
style: TextStyle(fontSize: 14, color: Colors.white)),
),
],
),
@@ -204,7 +224,8 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
return const SliverToBoxAdapter(child: LoadingWidget());
}
if (logic.recommendList.isEmpty) {
return const SliverToBoxAdapter(child: SizedBox(height: 300, child: CErrorWidget()));
return const SliverToBoxAdapter(
child: SizedBox(height: 300, child: CErrorWidget()));
}
return SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 16),
@@ -238,8 +259,10 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
onTap: () => Get.back(),
child: Container(
padding: const EdgeInsets.only(left: 10, right: 2, top: 2, bottom: 2),
decoration: const BoxDecoration(color: Colors.grey, shape: BoxShape.circle),
child: Icon(Icons.arrow_back_ios, color: Colors.black.withValues(alpha: 0.8)),
decoration:
const BoxDecoration(color: Colors.grey, shape: BoxShape.circle),
child: Icon(Icons.arrow_back_ios,
color: Colors.black.withValues(alpha: 0.8)),
),
);
}
@@ -260,7 +283,8 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
encrypt: false,
),
4.sizeBoxW,
Text(logic.anchor?.name ?? '', style: const TextStyle(fontSize: 14, color: Colors.white)),
Text(logic.anchor?.name ?? '',
style: const TextStyle(fontSize: 14, color: Colors.white)),
],
),
18.sizeBoxH,
@@ -275,9 +299,12 @@ class _LiveDetailPageState extends State<LiveDetailPage> {
onTap: () => logic.onShareAction(),
child: Row(
children: [
Image.asset('live_share.png'.livePath, width: 24, color: Colors.white),
Image.asset('live_share.png'.livePath,
width: 24, color: Colors.white),
2.sizeBoxW,
const Text('分享', style: TextStyle(fontSize: 12, color: Color(0xff999999))),
const Text('分享',
style:
TextStyle(fontSize: 12, color: Color(0xff999999))),
],
),
),
+49 -16
View File
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgmj/assets_tool/images.dart';
import 'package:hgmj/tools_base/widget/net_image_widget.dart';
import 'package:wydj/assets_tool/images.dart';
import 'package:wydj/tools_base/widget/net_image_widget.dart';
import '../../hj_utils/widget_utils.dart';
import 'live_detail_page.dart';
@@ -29,7 +29,8 @@ class LiveItemWidget extends StatelessWidget {
if (action != null) {
action?.call();
} else {
Get.to(() => LiveDetailPage(anchor: anchor), preventDuplicates: false);
Get.to(() => LiveDetailPage(anchor: anchor),
preventDuplicates: false);
}
},
child: _buildContent(),
@@ -50,7 +51,8 @@ class LiveItemWidget extends StatelessWidget {
return Stack(
children: [
Positioned.fill(
child: NetworkImageLoader(imageUrl: anchor?.coverImg ?? '', encrypt: false),
child: NetworkImageLoader(
imageUrl: anchor?.coverImg ?? '', encrypt: false),
),
Positioned(
left: 4,
@@ -61,7 +63,10 @@ class LiveItemWidget extends StatelessWidget {
textAlign: TextAlign.start,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w400),
style: TextStyle(
fontSize: 12,
color: Colors.white,
fontWeight: FontWeight.w400),
)),
Positioned(
top: 0,
@@ -84,7 +89,10 @@ class LiveItemWidget extends StatelessWidget {
),
child: Text(
'王牌主播',
style: TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.w400),
style: TextStyle(
fontSize: 10,
color: Colors.white,
fontWeight: FontWeight.w400),
),
)),
],
@@ -135,7 +143,8 @@ class LiveItemWidget extends StatelessWidget {
),
padding: EdgeInsets.all(2),
child: ClipOval(
child: NetworkImageLoader(imageUrl: anchor?.coverImg ?? '', encrypt: false),
child: NetworkImageLoader(
imageUrl: anchor?.coverImg ?? '', encrypt: false),
),
),
)),
@@ -158,7 +167,10 @@ class LiveItemWidget extends StatelessWidget {
children: [
Text(
anchor?.name ?? '',
style: TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w400),
style: TextStyle(
fontSize: 14,
color: Colors.white,
fontWeight: FontWeight.w400),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
@@ -178,7 +190,10 @@ class LiveItemWidget extends StatelessWidget {
),
child: Text(
'霸占TA>',
style: TextStyle(fontSize: 10, color: Color(0xff6A00FF), fontWeight: FontWeight.w400),
style: TextStyle(
fontSize: 10,
color: Color(0xff6A00FF),
fontWeight: FontWeight.w400),
),
),
],
@@ -195,14 +210,18 @@ class LiveItemWidget extends StatelessWidget {
return Stack(
children: [
Positioned.fill(
child: NetworkImageLoader(imageUrl: anchor?.coverImg ?? '', encrypt: false),
child: NetworkImageLoader(
imageUrl: anchor?.coverImg ?? '', encrypt: false),
),
Positioned(
left: 6,
bottom: 6,
child: Text(
anchor?.name ?? '',
style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w400),
style: TextStyle(
fontSize: 12,
color: Colors.white,
fontWeight: FontWeight.w400),
)),
if (index != null && index! < 4)
Positioned(
@@ -234,7 +253,10 @@ class LiveItemWidget extends StatelessWidget {
bottom: 6,
child: Text(
anchor?.name ?? '',
style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w400),
style: TextStyle(
fontSize: 12,
color: Colors.white,
fontWeight: FontWeight.w400),
)),
],
);
@@ -262,7 +284,10 @@ class LiveItemWidget extends StatelessWidget {
bottom: 6,
child: Text(
anchor?.name ?? '',
style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w400),
style: TextStyle(
fontSize: 12,
color: Colors.white,
fontWeight: FontWeight.w400),
)),
Positioned(
right: 6,
@@ -274,14 +299,19 @@ class LiveItemWidget extends StatelessWidget {
height: 8,
width: 8,
decoration: BoxDecoration(
color: (anchor?.isOnline ?? false) ? Color(0xff0AEBED) : Color(0xff656565),
color: (anchor?.isOnline ?? false)
? Color(0xff0AEBED)
: Color(0xff656565),
borderRadius: BorderRadius.circular(4),
),
),
SizedBox(width: 4),
Text(
(anchor?.isOnline ?? false) ? '直播中' : '离线',
style: TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.w400),
style: TextStyle(
fontSize: 10,
color: Colors.white,
fontWeight: FontWeight.w400),
)
],
)),
@@ -298,7 +328,10 @@ class LiveItemWidget extends StatelessWidget {
),
child: Text(
'${anchor?.viewCount?.humanizeFormat() ?? 0}人观众',
style: TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.w400),
style: TextStyle(
fontSize: 10,
color: Colors.white,
fontWeight: FontWeight.w400),
),
)),
],
+3 -2
View File
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgmj/hj_page/live/live_service.dart';
import 'package:wydj/hj_page/live/live_service.dart';
import 'live_model.dart';
@@ -26,7 +26,8 @@ class LiveMainLogic extends GetxController with GetTickerProviderStateMixin {
loadData() async {
liveMainModel = await LiveService.getLiveModuleList();
if (liveMainModel != null) {
if (liveMainModel?.module != null && liveMainModel?.module?.isNotEmpty == true) {
if (liveMainModel?.module != null &&
liveMainModel?.module?.isNotEmpty == true) {
liveTabs.clear();
liveTabs.add(LiveModule(id: '-1', title: '推荐')); //添加推荐数据
liveTabs.addAll(liveMainModel?.module ?? []);
+10 -7
View File
@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgmj/assets_tool/app_colors.dart';
import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart';
import 'package:hgmj/tools_base/loading/loading_center_widget.dart';
import 'package:hgmj/tools_base/widget/keep_alive_widget.dart';
import 'package:wydj/assets_tool/app_colors.dart';
import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart';
import 'package:wydj/tools_base/loading/loading_center_widget.dart';
import 'package:wydj/tools_base/widget/keep_alive_widget.dart';
import 'live_main_logic.dart';
import 'live_sub_page.dart';
@@ -29,7 +29,8 @@ class LiveMainPage extends StatelessWidget {
controller: logic.tabController,
children: List.generate(
logic.liveTabs.length,
(index) => LiveSubPage(tagData: logic.liveTabs[index]).keepAlive,
(index) =>
LiveSubPage(tagData: logic.liveTabs[index]).keepAlive,
),
),
),
@@ -58,11 +59,13 @@ class LiveMainPage extends StatelessWidget {
labelColor: Colors.white.withValues(alpha: .9),
labelStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
unselectedLabelColor: Colors.white.withValues(alpha: .45),
unselectedLabelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400),
unselectedLabelStyle:
const TextStyle(fontSize: 14, fontWeight: FontWeight.w400),
indicator: CustomIndicator(
height: 2,
width: 16,
borderRadius: const BorderRadius.only(topLeft: Radius.circular(1), topRight: Radius.circular(1)),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(1), topRight: Radius.circular(1)),
color: AppColors.actionRed,
),
),
+12 -8
View File
@@ -1,12 +1,13 @@
import 'package:hgmj/hj_model/list_base_model.dart';
import 'package:hgmj/hj_page/live/live_model.dart';
import 'package:hgmj/tools_base/net/http_manager.dart';
import 'package:hgmj/tools_base/net/net_manager.dart';
import 'package:wydj/hj_model/list_base_model.dart';
import 'package:wydj/hj_page/live/live_model.dart';
import 'package:wydj/tools_base/net/http_manager.dart';
import 'package:wydj/tools_base/net/net_manager.dart';
class LiveService {
//获取直播模块
static Future<LiveMainModel?> getLiveModuleList() async {
int time = netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000;
int time =
netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000;
final param = {'time': time};
final result = await httpManager.fetchResponseByPOST(
'/live/module/list/91porn',
@@ -22,7 +23,8 @@ class LiveService {
int? pageNumber,
int? pageSize,
}) async {
int time = netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000;
int time =
netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000;
final param = {
'time': time,
'id': id,
@@ -39,7 +41,8 @@ class LiveService {
//获取直播详情模块
static Future<LiveAnchor?> getLiveAnchorDetail({String? id}) async {
int time = netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000;
int time =
netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000;
final param = {
'time': time,
'id': id,
@@ -58,7 +61,8 @@ class LiveService {
int? pageNumber,
int? pageSize,
}) async {
int time = netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000;
int time =
netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000;
final param = {
'time': time,
'country': country,
+9 -5
View File
@@ -1,6 +1,6 @@
import 'package:hgmj/hj_model/list_base_model.dart';
import 'package:wydj/hj_model/list_base_model.dart';
import 'package:get/get.dart';
import 'package:hgmj/hj_page/live/live_service.dart';
import 'package:wydj/hj_page/live/live_service.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import '../mine/mine_vip/mine_charge_vip_page.dart';
@@ -50,7 +50,8 @@ class LiveSubLogic extends GetxController {
//tag直播列表
loadCountryAnchor({int pageNum = 1, bool showLoading = false}) async {
ListBaseModel<LiveAnchor>? liveMainModels = await LiveService.getLiveAnchorList(
ListBaseModel<LiveAnchor>? liveMainModels =
await LiveService.getLiveAnchorList(
id: tagData?.id ?? '',
pageNumber: pageNum,
);
@@ -58,12 +59,15 @@ class LiveSubLogic extends GetxController {
if (liveMainModels != null) {
currentPage = pageNum;
if (currentPage == 1) liveList.clear();
if (liveMainModels.list != null && liveMainModels.list?.isNotEmpty == true) {
if (liveMainModels.list != null &&
liveMainModels.list?.isNotEmpty == true) {
liveList.addAll(liveMainModels.list ?? []);
}
}
update();
liveMainModels?.hasNext == true ? controller?.loadComplete() : controller?.loadNoData();
liveMainModels?.hasNext == true
? controller?.loadComplete()
: controller?.loadNoData();
controller?.refreshCompleted();
}
+84 -35
View File
@@ -1,12 +1,12 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgmj/assets_tool/images.dart';
import 'package:hgmj/hj_page/live/live_item_widget.dart';
import 'package:hgmj/hj_utils/screen.dart';
import 'package:hgmj/tools_base/banner/ads_grid_view.dart';
import 'package:hgmj/tools_base/loading/loading_center_widget.dart';
import 'package:hgmj/tools_base/refresh/pull_refresh.dart';
import 'package:hgmj/tools_base/widget/card_swiper/src/swiper.dart';
import 'package:wydj/assets_tool/images.dart';
import 'package:wydj/hj_page/live/live_item_widget.dart';
import 'package:wydj/hj_utils/screen.dart';
import 'package:wydj/tools_base/banner/ads_grid_view.dart';
import 'package:wydj/tools_base/loading/loading_center_widget.dart';
import 'package:wydj/tools_base/refresh/pull_refresh.dart';
import 'package:wydj/tools_base/widget/card_swiper/src/swiper.dart';
import 'live_model.dart';
import 'live_sub_logic.dart';
@@ -28,7 +28,8 @@ class _LiveSubPageState extends State<LiveSubPage> {
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage('live_main_bg.webp'.livePath), fit: BoxFit.fill),
image: DecorationImage(
image: AssetImage('live_main_bg.webp'.livePath), fit: BoxFit.fill),
),
child: GetBuilder<LiveSubLogic>(
init: LiveSubLogic(tagData: widget.tagData),
@@ -47,7 +48,8 @@ class _LiveSubPageState extends State<LiveSubPage> {
Widget _buildContent(LiveSubLogic logic) {
//列表样式
if (!logic.isRecom) {
return CustomScrollView(slivers: [_buildAdBanner(), _buildAnchorGrid(logic)]);
return CustomScrollView(
slivers: [_buildAdBanner(), _buildAnchorGrid(logic)]);
}
//推荐样式
if (logic.liveMainModel?.recom == null) return const LoadingCenterWidget();
@@ -71,10 +73,12 @@ class _LiveSubPageState extends State<LiveSubPage> {
//国家/标签主播列表
Widget _buildAnchorGrid(LiveSubLogic logic) {
if (logic.loading) {
return const SliverToBoxAdapter(child: SizedBox(height: 200, child: LoadingCenterWidget()));
return const SliverToBoxAdapter(
child: SizedBox(height: 200, child: LoadingCenterWidget()));
}
if (logic.liveList.isEmpty) {
return SliverToBoxAdapter(child: CErrorWidget(retryOnTap: () => logic.loadData()));
return SliverToBoxAdapter(
child: CErrorWidget(retryOnTap: () => logic.loadData()));
}
return SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 16),
@@ -86,7 +90,8 @@ class _LiveSubPageState extends State<LiveSubPage> {
childAspectRatio: 168 / 105,
),
delegate: SliverChildBuilderDelegate(
(_, index) => LiveItemWidget(showType: 5, anchor: logic.liveList[index]),
(_, index) =>
LiveItemWidget(showType: 5, anchor: logic.liveList[index]),
childCount: logic.liveList.length,
),
),
@@ -107,13 +112,47 @@ class _LiveSubPageState extends State<LiveSubPage> {
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);
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);
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 _buildGridSectionHor(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);
return _buildGridSectionHor(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);
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':
@@ -128,7 +167,9 @@ class _LiveSubPageState extends State<LiveSubPage> {
return Stack(
alignment: Alignment.topCenter,
children: [
Column(mainAxisSize: MainAxisSize.min, children: [178.sizeBoxH, section, 10.sizeBoxH]),
Column(
mainAxisSize: MainAxisSize.min,
children: [178.sizeBoxH, section, 10.sizeBoxH]),
Positioned(
top: 20,
child: GestureDetector(
@@ -156,7 +197,8 @@ class _LiveSubPageState extends State<LiveSubPage> {
final anchors = recom?.anchors;
return Container(
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage(bg.livePath), fit: BoxFit.fill),
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),
@@ -177,7 +219,8 @@ class _LiveSubPageState extends State<LiveSubPage> {
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
//index 仅 showType==2 用于渲染前三角标,其余样式忽略
itemBuilder: (_, index) => LiveItemWidget(showType: showType, anchor: anchors?[index], index: index),
itemBuilder: (_, index) => LiveItemWidget(
showType: showType, anchor: anchors?[index], index: index),
),
if (bottomSpace > 0) bottomSpace.sizeBoxH,
],
@@ -187,21 +230,22 @@ class _LiveSubPageState extends State<LiveSubPage> {
//宫格类区块(九宫格/六圆形/四宫格/六宫格 共用)横向排序
Widget _buildGridSectionHor(
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,
}) {
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),
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),
@@ -210,7 +254,7 @@ class _LiveSubPageState extends State<LiveSubPage> {
final width = c.maxWidth;
final itemWidth = (width - 12) / 2;
return Column(
return Column(
children: [
18.sizeBoxH,
Image.asset(title.livePath, height: titleHeight),
@@ -231,7 +275,10 @@ class _LiveSubPageState extends State<LiveSubPage> {
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
//index 仅 showType==2 用于渲染前三角标,其余样式忽略
itemBuilder: (_, index) => LiveItemWidget(showType: showType, anchor: anchors?[index], index: index),
itemBuilder: (_, index) => LiveItemWidget(
showType: showType,
anchor: anchors?[index],
index: index),
),
),
if (bottomSpace > 0) bottomSpace.sizeBoxH,
@@ -274,7 +321,8 @@ class _LiveSubPageState extends State<LiveSubPage> {
viewportFraction: 0.8,
scale: 0.93,
itemCount: anchors?.length ?? 0,
itemBuilder: (c, index) => LiveItemWidget(showType: 4, anchor: anchors?[index]),
itemBuilder: (c, index) =>
LiveItemWidget(showType: 4, anchor: anchors?[index]),
),
),
],
@@ -297,7 +345,8 @@ class _LiveSubPageState extends State<LiveSubPage> {
itemCount: anchors?.length ?? 0,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (_, index) => LiveItemWidget(showType: 5, anchor: anchors?[index]),
itemBuilder: (_, index) =>
LiveItemWidget(showType: 5, anchor: anchors?[index]),
),
);
}