This commit is contained in:
2026-03-07 17:24:59 +08:00
parent 4418ebecac
commit b0ec8ab4bd
417 changed files with 42546 additions and 2 deletions

View File

@@ -0,0 +1,372 @@
import 'package:flutter/material.dart';
import 'package:flutter_dmzj/app/app_style.dart';
import 'package:flutter_dmzj/models/comic/recommend_model.dart';
import 'package:flutter_dmzj/modules/comic/home/recommend/comic_recommend_controller.dart';
import 'package:flutter_dmzj/widgets/keep_alive_wrapper.dart';
import 'package:flutter_dmzj/widgets/net_image.dart';
import 'package:flutter_dmzj/widgets/page_list_view.dart';
import 'package:flutter_dmzj/widgets/refresh_until_widget.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:flutter_swiper_view/flutter_swiper_view.dart';
import 'package:get/get.dart';
class ComicRecommendView extends StatelessWidget {
final ComicRecommendController controller;
ComicRecommendView({Key? key})
: controller = Get.put(ComicRecommendController()),
super(key: key);
@override
Widget build(BuildContext context) {
return KeepAliveWrapper(
child: PageListView(
pageController: controller,
padding: AppStyle.edgeInsetsH12,
firstRefresh: true,
loadMore: false,
showPageLoadding: true,
itemBuilder: (context, i) {
var item = controller.list[i];
//大图推荐
if (item.categoryId == 109) {
return buildBanner(item);
}
//随便看看
// if (item.categoryId == 50) {
// return buildCard(
// context,
// child: buildTreeColumnGridView(item.data),
// title: item.title.toString(),
// action: buildRefresh(onRefresh: controller.loadRandom),
// );
// }
//我的订阅
if (item.categoryId == 49) {
return buildCard(
context,
child: buildTreeColumnGridView(item.data),
title: item.title.toString(),
action: buildShowMore(onTap: controller.toMySubscribe),
);
}
//近期必看\国漫\热门连载\最新上架
if (item.categoryId == 110 ||
item.categoryId == 111 ||
item.categoryId == 112 ||
item.categoryId == 56) {
Widget? action;
//刷新国漫
if (item.categoryId == 110) {
action = buildRefresh(onRefresh: controller.refreshRecommend);
}
if (item.categoryId == 111) {
action = buildRefresh(onRefresh: controller.refreshGuoman);
}
if (item.categoryId == 112) {
action = buildRefresh(onRefresh: controller.refreshHot);
}
return buildCard(
context,
child: buildTreeColumnGridView(item.data),
title: item.title.toString(),
action: action,
);
}
//火热专题\美漫大事件\条漫
if (item.categoryId == 48 ||
item.categoryId == 53 ||
item.categoryId == 55) {
return buildCard(
context,
child: buildTwoColumnGridView(item.data),
title: item.title.toString(),
action: item.categoryId == 48
? buildShowMore(onTap: controller.toSpecial)
: null,
);
}
//大师
if (item.categoryId == 51) {
return buildCard(
context,
child: buildAuthorGridView(item.data),
title: item.title.toString(),
);
}
return buildCard(
context,
child: buildTreeColumnGridView(item.data),
title: item.title.toString(),
);
},
),
);
}
Widget buildCard(
BuildContext context, {
required Widget child,
required String title,
Widget? action,
}) {
return Padding(
padding: AppStyle.edgeInsetsB8,
child: Container(
decoration: BoxDecoration(
borderRadius: AppStyle.radius8,
),
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Text(
title,
style: const TextStyle(
fontSize: 16, height: 1.0, fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 48,
child: action,
),
],
),
child,
],
),
),
);
}
Widget buildShowMore({required Function() onTap}) {
return GestureDetector(
onTap: onTap,
child: const Row(
children: [
Text(
"查看更多",
style: TextStyle(fontSize: 14, color: Colors.grey),
),
Icon(Icons.chevron_right, size: 18, color: Colors.grey),
],
),
);
}
Widget buildRefresh({required Future Function() onRefresh}) {
return RefreshUntilWidget(onRefresh: onRefresh, text: "换一批");
}
Widget buildBanner(ComicRecommendModel item) {
return Padding(
padding: AppStyle.edgeInsetsB12,
child: ClipRRect(
borderRadius: AppStyle.radius4,
child: AspectRatio(
aspectRatio: 75 / 40,
child: Swiper(
itemWidth: 750,
itemHeight: 400,
autoplay: true,
itemCount: item.data.length,
itemBuilder: (_, i) => NetImage(
item.data[i].cover,
width: 750,
height: 400,
),
onTap: (i) {
controller.openDetail(item.data[i]);
},
pagination: SwiperCustomPagination(
builder: (BuildContext context, SwiperPluginConfig config) {
return Align(
alignment: Alignment.bottomCenter,
child: Container(
padding: const EdgeInsets.only(
left: 8,
right: 12,
top: 4,
bottom: 4,
),
//color: Colors.black12,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Colors.black38,
Colors.transparent,
],
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Text(
item.data[config.activeIndex].title,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 14, color: Colors.white),
),
),
AppStyle.hGap8,
PageIndicator(
controller: config.pageController!,
count: config.itemCount,
size: 10,
layout: PageIndicatorLayout.SCALE,
),
],
),
),
);
},
),
),
),
),
);
}
Widget buildTreeColumnGridView(List<ComicRecommendItemModel> items) {
return MasonryGridView.count(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 3,
mainAxisSpacing: 12,
crossAxisSpacing: 12,
itemCount: items.length,
itemBuilder: (_, i) {
var item = items[i];
return InkWell(
onTap: () => controller.openDetail(item),
borderRadius: AppStyle.radius4,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: AppStyle.radius4,
child: AspectRatio(
aspectRatio: 27 / 36,
child: NetImage(
item.cover,
width: 270,
height: 360,
),
),
),
AppStyle.vGap8,
Text(
item.title,
maxLines: 1,
style: const TextStyle(height: 1.2),
overflow: TextOverflow.ellipsis,
),
Text(
item.subTitle ?? item.status ?? '',
maxLines: 1,
style: const TextStyle(
height: 1.2,
fontSize: 12,
color: Colors.grey,
overflow: TextOverflow.ellipsis,
),
),
AppStyle.vGap8,
],
),
);
},
);
}
Widget buildAuthorGridView(List<ComicRecommendItemModel> items) {
return MasonryGridView.count(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 3,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
itemCount: items.length,
itemBuilder: (_, i) {
var item = items[i];
return InkWell(
onTap: () => controller.openDetail(item),
borderRadius: AppStyle.radius8,
child: Padding(
padding: AppStyle.edgeInsetsA12,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
NetImage(
item.cover,
width: 56,
height: 56,
borderRadius: 32,
),
Padding(
padding: AppStyle.edgeInsetsV8,
child: Text(
item.title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(height: 1.2, fontSize: 12),
),
),
],
),
),
);
},
);
}
Widget buildTwoColumnGridView(List<ComicRecommendItemModel> items) {
return MasonryGridView.count(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 2,
mainAxisSpacing: 12,
crossAxisSpacing: 12,
itemCount: items.length,
itemBuilder: (_, i) {
var item = items[i];
return InkWell(
onTap: () => controller.openDetail(item),
borderRadius: AppStyle.radius4,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: AppStyle.radius4,
child: AspectRatio(
aspectRatio: 32 / 17,
child: NetImage(
item.cover,
width: 320,
height: 170,
),
),
),
Padding(
padding: AppStyle.edgeInsetsV8,
child: Text(
item.title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(height: 1.2),
),
),
],
),
);
},
);
}
}