feat: 首页番剧&样式
This commit is contained in:
@ -253,4 +253,25 @@ class Api {
|
|||||||
|
|
||||||
// 取消追番
|
// 取消追番
|
||||||
static const String bangumiDel = '/pgc/web/follow/del';
|
static const String bangumiDel = '/pgc/web/follow/del';
|
||||||
|
|
||||||
|
// 番剧列表
|
||||||
|
// https://api.bilibili.com/pgc/season/index/result?
|
||||||
|
// st=1&
|
||||||
|
// order=3
|
||||||
|
// season_version=-1 全部-1 正片1 电影2 其他3
|
||||||
|
// spoken_language_type=-1 全部-1 原生1 中文配音2
|
||||||
|
// area=-1&
|
||||||
|
// is_finish=-1&
|
||||||
|
// copyright=-1&
|
||||||
|
// season_status=-1&
|
||||||
|
// season_month=-1&
|
||||||
|
// year=-1&
|
||||||
|
// style_id=-1&
|
||||||
|
// sort=0&
|
||||||
|
// page=1&
|
||||||
|
// season_type=1&
|
||||||
|
// pagesize=20&
|
||||||
|
// type=1
|
||||||
|
static const String bangumiList =
|
||||||
|
'/pgc/season/index/result?st=1&order=3&season_version=-1&spoken_language_type=-1&area=-1&is_finish=-1©right=-1&season_status=-1&season_month=-1&year=-1&style_id=-1&sort=0&season_type=1&pagesize=20&type=1';
|
||||||
}
|
}
|
||||||
|
20
lib/http/bangumi.dart
Normal file
20
lib/http/bangumi.dart
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import 'package:pilipala/http/index.dart';
|
||||||
|
import 'package:pilipala/models/bangumi/list.dart';
|
||||||
|
|
||||||
|
class BangumiHttp {
|
||||||
|
static Future bangumiList({int? page}) async {
|
||||||
|
var res = await Request().get(Api.bangumiList, data: {'page': page});
|
||||||
|
if (res.data['code'] == 0) {
|
||||||
|
return {
|
||||||
|
'status': true,
|
||||||
|
'data': BangumiListDataModel.fromJson(res.data['data'])
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
'status': false,
|
||||||
|
'data': [],
|
||||||
|
'msg': res.data['message'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
lib/models/bangumi/list.dart
Normal file
85
lib/models/bangumi/list.dart
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
class BangumiListDataModel {
|
||||||
|
BangumiListDataModel({
|
||||||
|
this.hasNext,
|
||||||
|
this.list,
|
||||||
|
this.num,
|
||||||
|
this.size,
|
||||||
|
this.total,
|
||||||
|
});
|
||||||
|
|
||||||
|
int? hasNext;
|
||||||
|
List? list;
|
||||||
|
int? num;
|
||||||
|
int? size;
|
||||||
|
int? total;
|
||||||
|
|
||||||
|
BangumiListDataModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
hasNext = json['has_next'];
|
||||||
|
list = json['list'] != null
|
||||||
|
? json['list']
|
||||||
|
.map<BangumiListItemModel>((e) => BangumiListItemModel.fromJson(e))
|
||||||
|
.toList()
|
||||||
|
: [];
|
||||||
|
num = json['num'];
|
||||||
|
size = json['size'];
|
||||||
|
total = json['total'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BangumiListItemModel {
|
||||||
|
BangumiListItemModel({
|
||||||
|
this.badge,
|
||||||
|
this.badgeType,
|
||||||
|
this.cover,
|
||||||
|
// this.firstEp,
|
||||||
|
this.indexShow,
|
||||||
|
this.isFinish,
|
||||||
|
this.link,
|
||||||
|
this.mediaId,
|
||||||
|
this.order,
|
||||||
|
this.orderType,
|
||||||
|
this.score,
|
||||||
|
this.seasonId,
|
||||||
|
this.seaconStatus,
|
||||||
|
this.seasonType,
|
||||||
|
this.subTitle,
|
||||||
|
this.title,
|
||||||
|
this.titleIcon,
|
||||||
|
});
|
||||||
|
|
||||||
|
String? badge;
|
||||||
|
int? badgeType;
|
||||||
|
String? cover;
|
||||||
|
String? indexShow;
|
||||||
|
int? isFinish;
|
||||||
|
String? link;
|
||||||
|
int? mediaId;
|
||||||
|
String? order;
|
||||||
|
String? orderType;
|
||||||
|
String? score;
|
||||||
|
int? seasonId;
|
||||||
|
int? seaconStatus;
|
||||||
|
int? seasonType;
|
||||||
|
String? subTitle;
|
||||||
|
String? title;
|
||||||
|
String? titleIcon;
|
||||||
|
|
||||||
|
BangumiListItemModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
badge = json['badge'] == '' ? null : json['badge'];
|
||||||
|
badgeType = json['badge_type'];
|
||||||
|
cover = json['cover'];
|
||||||
|
indexShow = json['index_show'];
|
||||||
|
isFinish = json['is_finish'];
|
||||||
|
link = json['link'];
|
||||||
|
mediaId = json['media_id'];
|
||||||
|
order = json['order'];
|
||||||
|
orderType = json['order_type'];
|
||||||
|
score = json['score'];
|
||||||
|
seasonId = json['season_id'];
|
||||||
|
seaconStatus = json['seacon_status'];
|
||||||
|
seasonType = json['season_type'];
|
||||||
|
subTitle = json['sub_title'];
|
||||||
|
title = json['title'];
|
||||||
|
titleIcon = json['title_icon'];
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/http/bangumi.dart';
|
||||||
|
import 'package:pilipala/models/bangumi/list.dart';
|
||||||
|
|
||||||
class BangumiController extends GetxController {}
|
class BangumiController extends GetxController {
|
||||||
|
final ScrollController scrollController = ScrollController();
|
||||||
|
RxList<BangumiListItemModel> bangumiList = [BangumiListItemModel()].obs;
|
||||||
|
int _currentPage = 1;
|
||||||
|
bool isLoadingMore = true;
|
||||||
|
|
||||||
|
Future queryBangumiListFeed({type = 'init'}) async {
|
||||||
|
var result = await BangumiHttp.bangumiList(page: _currentPage);
|
||||||
|
if (result['status']) {
|
||||||
|
if (type == 'init') {
|
||||||
|
bangumiList.value = result['data'].list;
|
||||||
|
} else {
|
||||||
|
bangumiList.addAll(result['data'].list);
|
||||||
|
}
|
||||||
|
_currentPage += 1;
|
||||||
|
} else {}
|
||||||
|
isLoadingMore = false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上拉加载
|
||||||
|
Future onLoad() async {
|
||||||
|
queryBangumiListFeed(type: 'onLoad');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,15 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/common/constants.dart';
|
||||||
|
import 'package:pilipala/common/widgets/http_error.dart';
|
||||||
|
import 'package:pilipala/pages/main/index.dart';
|
||||||
|
import 'package:pilipala/pages/rcmd/view.dart';
|
||||||
|
|
||||||
|
import 'controller.dart';
|
||||||
|
import 'widgets/bangumu_card_v.dart';
|
||||||
|
|
||||||
class BangumiPage extends StatefulWidget {
|
class BangumiPage extends StatefulWidget {
|
||||||
const BangumiPage({super.key});
|
const BangumiPage({super.key});
|
||||||
@ -7,12 +18,106 @@ class BangumiPage extends StatefulWidget {
|
|||||||
State<BangumiPage> createState() => _BangumiPageState();
|
State<BangumiPage> createState() => _BangumiPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BangumiPageState extends State<BangumiPage> {
|
class _BangumiPageState extends State<BangumiPage>
|
||||||
|
with AutomaticKeepAliveClientMixin {
|
||||||
|
final BangumiController _bangumidController = Get.put(BangumiController());
|
||||||
|
late Future? _futureBuilderFuture;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get wantKeepAlive => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
ScrollController scrollController = _bangumidController.scrollController;
|
||||||
|
StreamController<bool> mainStream =
|
||||||
|
Get.find<MainController>().bottomBarStream;
|
||||||
|
_futureBuilderFuture = _bangumidController.queryBangumiListFeed();
|
||||||
|
scrollController.addListener(
|
||||||
|
() async {
|
||||||
|
if (scrollController.position.pixels >=
|
||||||
|
scrollController.position.maxScrollExtent - 200) {
|
||||||
|
if (!_bangumidController.isLoadingMore) {
|
||||||
|
await _bangumidController.onLoad();
|
||||||
|
await Future.delayed(const Duration(milliseconds: 200));
|
||||||
|
_bangumidController.isLoadingMore = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final ScrollDirection direction =
|
||||||
|
scrollController.position.userScrollDirection;
|
||||||
|
if (direction == ScrollDirection.forward) {
|
||||||
|
mainStream.add(true);
|
||||||
|
} else if (direction == ScrollDirection.reverse) {
|
||||||
|
mainStream.add(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const Scaffold(
|
return Container(
|
||||||
body: Center(
|
clipBehavior: Clip.hardEdge,
|
||||||
child: Text('还在开发中'),
|
margin: const EdgeInsets.only(
|
||||||
|
left: StyleString.safeSpace, right: StyleString.safeSpace),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(StyleString.imgRadius),
|
||||||
|
),
|
||||||
|
child: RefreshIndicator(
|
||||||
|
onRefresh: () async {
|
||||||
|
return Future.delayed(const Duration(seconds: 2));
|
||||||
|
},
|
||||||
|
child: CustomScrollView(
|
||||||
|
controller: _bangumidController.scrollController,
|
||||||
|
slivers: [
|
||||||
|
SliverPadding(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
sliver: FutureBuilder(
|
||||||
|
future: _futureBuilderFuture,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
Map data = snapshot.data as Map;
|
||||||
|
if (data['status']) {
|
||||||
|
return Obx(() => contentGrid(_bangumidController,
|
||||||
|
_bangumidController.bangumiList));
|
||||||
|
} else {
|
||||||
|
return HttpError(
|
||||||
|
errMsg: data['msg'],
|
||||||
|
fn: () => {},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return contentGrid(_bangumidController, []);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const LoadingMore()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget contentGrid(ctr, bangumiList) {
|
||||||
|
return SliverGrid(
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
// 行间距
|
||||||
|
mainAxisSpacing: StyleString.cardSpace - 2,
|
||||||
|
// 列间距
|
||||||
|
crossAxisSpacing: StyleString.cardSpace,
|
||||||
|
// 列数
|
||||||
|
crossAxisCount: 3,
|
||||||
|
mainAxisExtent: Get.size.width / 3 / 0.65 + 45,
|
||||||
|
),
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(BuildContext context, int index) {
|
||||||
|
return bangumiList!.isNotEmpty
|
||||||
|
? BangumiCardV(bangumiItem: bangumiList[index])
|
||||||
|
: const SizedBox();
|
||||||
|
},
|
||||||
|
childCount: bangumiList!.isNotEmpty ? bangumiList!.length : 10,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
199
lib/pages/bangumi/widgets/bangumu_card_v.dart
Normal file
199
lib/pages/bangumi/widgets/bangumu_card_v.dart
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/common/constants.dart';
|
||||||
|
import 'package:pilipala/common/widgets/badge.dart';
|
||||||
|
import 'package:pilipala/http/search.dart';
|
||||||
|
import 'package:pilipala/models/bangumi/info.dart';
|
||||||
|
import 'package:pilipala/models/common/search_type.dart';
|
||||||
|
import 'package:pilipala/utils/utils.dart';
|
||||||
|
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||||
|
|
||||||
|
// 视频卡片 - 垂直布局
|
||||||
|
class BangumiCardV extends StatelessWidget {
|
||||||
|
// ignore: prefer_typing_uninitialized_variables
|
||||||
|
final bangumiItem;
|
||||||
|
final Function()? longPress;
|
||||||
|
final Function()? longPressEnd;
|
||||||
|
|
||||||
|
const BangumiCardV({
|
||||||
|
Key? key,
|
||||||
|
required this.bangumiItem,
|
||||||
|
this.longPress,
|
||||||
|
this.longPressEnd,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
String heroTag = Utils.makeHeroTag(bangumiItem.mediaId);
|
||||||
|
return Card(
|
||||||
|
elevation: 0,
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: StyleString.mdRadius,
|
||||||
|
),
|
||||||
|
margin: EdgeInsets.zero,
|
||||||
|
child: GestureDetector(
|
||||||
|
// onLongPress: () {
|
||||||
|
// if (longPress != null) {
|
||||||
|
// longPress!();
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// onLongPressEnd: (details) {
|
||||||
|
// if (longPressEnd != null) {
|
||||||
|
// longPressEnd!();
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
int seasonId = bangumiItem.seasonId;
|
||||||
|
SmartDialog.showLoading(msg: '获取中...');
|
||||||
|
var res = await SearchHttp.bangumiInfo(seasonId: seasonId);
|
||||||
|
SmartDialog.dismiss().then((value) {
|
||||||
|
if (res['status']) {
|
||||||
|
EpisodeItem episode = res['data'].episodes.first;
|
||||||
|
String bvid = episode.bvid!;
|
||||||
|
int cid = episode.cid!;
|
||||||
|
String pic = episode.cover!;
|
||||||
|
String heroTag = Utils.makeHeroTag(cid);
|
||||||
|
Get.toNamed(
|
||||||
|
'/video?bvid=$bvid&cid=$cid&seasonId=$seasonId',
|
||||||
|
arguments: {
|
||||||
|
'pic': pic,
|
||||||
|
'heroTag': heroTag,
|
||||||
|
'videoType': SearchType.media_bangumi,
|
||||||
|
'bangumiItem': res['data'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: StyleString.imgRadius,
|
||||||
|
topRight: StyleString.imgRadius,
|
||||||
|
bottomLeft: StyleString.imgRadius,
|
||||||
|
bottomRight: StyleString.imgRadius,
|
||||||
|
),
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: 0.65,
|
||||||
|
child: LayoutBuilder(builder: (context, boxConstraints) {
|
||||||
|
double maxWidth = boxConstraints.maxWidth;
|
||||||
|
double maxHeight = boxConstraints.maxHeight;
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
Hero(
|
||||||
|
tag: heroTag,
|
||||||
|
child: NetworkImgLayer(
|
||||||
|
src: bangumiItem.cover,
|
||||||
|
width: maxWidth,
|
||||||
|
height: maxHeight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (bangumiItem.badge != null)
|
||||||
|
pBadge(bangumiItem.badge, context, 6, 6, null, null),
|
||||||
|
pBadge(bangumiItem.order, context, null, null, 6, 6,
|
||||||
|
type: 'gray'),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
BangumiContent(bangumiItem: bangumiItem)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BangumiContent extends StatelessWidget {
|
||||||
|
// ignore: prefer_typing_uninitialized_variables
|
||||||
|
final bangumiItem;
|
||||||
|
const BangumiContent({Key? key, required this.bangumiItem}) : super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Expanded(
|
||||||
|
child: Padding(
|
||||||
|
// 多列
|
||||||
|
padding: const EdgeInsets.fromLTRB(4, 5, 0, 3),
|
||||||
|
// 单列
|
||||||
|
// padding: const EdgeInsets.fromLTRB(14, 10, 4, 8),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
bangumiItem.title,
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
letterSpacing: 0.3,
|
||||||
|
),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: LayoutBuilder(builder:
|
||||||
|
(BuildContext context, BoxConstraints constraints) {
|
||||||
|
return SizedBox(
|
||||||
|
width: constraints.maxWidth,
|
||||||
|
child: Text(
|
||||||
|
bangumiItem.indexShow,
|
||||||
|
maxLines: 1,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize:
|
||||||
|
Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
// SizedBox(
|
||||||
|
// width: 20,
|
||||||
|
// height: 20,
|
||||||
|
// child: IconButton(
|
||||||
|
// tooltip: '稍后再看',
|
||||||
|
// style: ButtonStyle(
|
||||||
|
// padding: MaterialStateProperty.all(EdgeInsets.zero),
|
||||||
|
// ),
|
||||||
|
// onPressed: () async {
|
||||||
|
// var res =
|
||||||
|
// await UserHttp.toViewLater(bvid: videoItem.bvid);
|
||||||
|
// SmartDialog.showToast(res['msg']);
|
||||||
|
// },
|
||||||
|
// icon: Icon(
|
||||||
|
// Icons.more_vert_outlined,
|
||||||
|
// color: Theme.of(context).colorScheme.outline,
|
||||||
|
// size: 14,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// Row(
|
||||||
|
// children: [
|
||||||
|
// StatView(
|
||||||
|
// theme: 'black',
|
||||||
|
// view: videoItem.stat.view,
|
||||||
|
// ),
|
||||||
|
// const SizedBox(width: 6),
|
||||||
|
// StatDanMu(
|
||||||
|
// theme: 'black',
|
||||||
|
// danmu: videoItem.stat.danmaku,
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -41,10 +41,9 @@ class _HomePageState extends State<HomePage>
|
|||||||
CustomAppBar(stream: stream, ctr: _homeController),
|
CustomAppBar(stream: stream, ctr: _homeController),
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.only(left: 12, right: 12, bottom: 4),
|
padding: const EdgeInsets.only(left: 12, right: 12, bottom: 4),
|
||||||
child: Stack(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Align(
|
Expanded(
|
||||||
alignment: Alignment.center,
|
|
||||||
child: Theme(
|
child: Theme(
|
||||||
data: ThemeData(
|
data: ThemeData(
|
||||||
splashColor: Colors.transparent, // 点击时的水波纹颜色设置为透明
|
splashColor: Colors.transparent, // 点击时的水波纹颜色设置为透明
|
||||||
@ -93,6 +92,23 @@ class _HomePageState extends State<HomePage>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
child: IconButton(
|
||||||
|
tooltip: '全部分类',
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: MaterialStateProperty.all(EdgeInsets.zero),
|
||||||
|
),
|
||||||
|
onPressed: () async {},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.dataset_outlined,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
size: 19,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 14)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -52,47 +52,54 @@ class _LivePageState extends State<LivePage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return RefreshIndicator(
|
return Container(
|
||||||
onRefresh: () async {
|
clipBehavior: Clip.hardEdge,
|
||||||
return await _liveController.onRefresh();
|
margin: const EdgeInsets.only(
|
||||||
},
|
left: StyleString.safeSpace, right: StyleString.safeSpace),
|
||||||
child: CustomScrollView(
|
decoration: const BoxDecoration(
|
||||||
controller: _liveController.scrollController,
|
borderRadius: BorderRadius.all(StyleString.imgRadius),
|
||||||
slivers: [
|
),
|
||||||
SliverPadding(
|
child: RefreshIndicator(
|
||||||
// 单列布局 EdgeInsets.zero
|
onRefresh: () async {
|
||||||
padding: const EdgeInsets.fromLTRB(
|
return await _liveController.onRefresh();
|
||||||
StyleString.safeSpace, 0, StyleString.safeSpace, 0),
|
},
|
||||||
sliver: FutureBuilder(
|
child: CustomScrollView(
|
||||||
future: _liveController.queryLiveList('init'),
|
controller: _liveController.scrollController,
|
||||||
builder: (context, snapshot) {
|
slivers: [
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
SliverPadding(
|
||||||
Map data = snapshot.data as Map;
|
// 单列布局 EdgeInsets.zero
|
||||||
if (data['status']) {
|
padding: EdgeInsets.zero,
|
||||||
return Obx(() =>
|
sliver: FutureBuilder(
|
||||||
contentGrid(_liveController, _liveController.liveList));
|
future: _liveController.queryLiveList('init'),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
Map data = snapshot.data as Map;
|
||||||
|
if (data['status']) {
|
||||||
|
return Obx(() => contentGrid(
|
||||||
|
_liveController, _liveController.liveList));
|
||||||
|
} else {
|
||||||
|
return HttpError(
|
||||||
|
errMsg: data['msg'],
|
||||||
|
fn: () => {},
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return HttpError(
|
// 缓存数据
|
||||||
errMsg: data['msg'],
|
if (_liveController.liveList.length > 1) {
|
||||||
fn: () => {},
|
return contentGrid(
|
||||||
);
|
_liveController, _liveController.liveList);
|
||||||
|
}
|
||||||
|
// 骨架屏
|
||||||
|
else {
|
||||||
|
return contentGrid(_liveController, []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
// 缓存数据
|
),
|
||||||
if (_liveController.liveList.length > 1) {
|
|
||||||
return contentGrid(
|
|
||||||
_liveController, _liveController.liveList);
|
|
||||||
}
|
|
||||||
// 骨架屏
|
|
||||||
else {
|
|
||||||
return contentGrid(_liveController, []);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
const LoadingMore()
|
||||||
const LoadingMore()
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -57,49 +57,56 @@ class _RcmdPageState extends State<RcmdPage>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
return RefreshIndicator(
|
return Container(
|
||||||
onRefresh: () async {
|
clipBehavior: Clip.hardEdge,
|
||||||
return await _rcmdController.onRefresh();
|
margin: const EdgeInsets.only(
|
||||||
},
|
left: StyleString.safeSpace, right: StyleString.safeSpace),
|
||||||
child: CustomScrollView(
|
decoration: const BoxDecoration(
|
||||||
controller: _rcmdController.scrollController,
|
borderRadius: BorderRadius.all(StyleString.imgRadius),
|
||||||
slivers: [
|
),
|
||||||
SliverPadding(
|
child: RefreshIndicator(
|
||||||
// 单列布局 EdgeInsets.zero
|
onRefresh: () async {
|
||||||
padding: _rcmdController.crossAxisCount == 1
|
return await _rcmdController.onRefresh();
|
||||||
? EdgeInsets.zero
|
},
|
||||||
: const EdgeInsets.fromLTRB(
|
child: CustomScrollView(
|
||||||
StyleString.safeSpace, 0, StyleString.safeSpace, 0),
|
controller: _rcmdController.scrollController,
|
||||||
sliver: FutureBuilder(
|
slivers: [
|
||||||
future: _rcmdController.queryRcmdFeed('init'),
|
SliverPadding(
|
||||||
builder: (context, snapshot) {
|
// 单列布局 EdgeInsets.zero
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
padding: _rcmdController.crossAxisCount == 1
|
||||||
Map data = snapshot.data as Map;
|
? EdgeInsets.zero
|
||||||
if (data['status']) {
|
: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
||||||
return Obx(() => contentGrid(
|
sliver: FutureBuilder(
|
||||||
_rcmdController, _rcmdController.videoList));
|
future: _rcmdController.queryRcmdFeed('init'),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
Map data = snapshot.data as Map;
|
||||||
|
if (data['status']) {
|
||||||
|
return Obx(() => contentGrid(
|
||||||
|
_rcmdController, _rcmdController.videoList));
|
||||||
|
} else {
|
||||||
|
return HttpError(
|
||||||
|
errMsg: data['msg'],
|
||||||
|
fn: () => {},
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return HttpError(
|
// 缓存数据
|
||||||
errMsg: data['msg'],
|
if (_rcmdController.videoList.length > 1) {
|
||||||
fn: () => {},
|
return contentGrid(
|
||||||
);
|
_rcmdController, _rcmdController.videoList);
|
||||||
|
}
|
||||||
|
// 骨架屏
|
||||||
|
else {
|
||||||
|
return contentGrid(_rcmdController, []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
// 缓存数据
|
),
|
||||||
if (_rcmdController.videoList.length > 1) {
|
|
||||||
return contentGrid(
|
|
||||||
_rcmdController, _rcmdController.videoList);
|
|
||||||
}
|
|
||||||
// 骨架屏
|
|
||||||
else {
|
|
||||||
return contentGrid(_rcmdController, []);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
const LoadingMore()
|
||||||
const LoadingMore()
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user