mod: 搜索页面样式

This commit is contained in:
guozhigq
2023-08-06 14:55:13 +08:00
parent c83f70c08a
commit f5f1ffb2be
7 changed files with 284 additions and 202 deletions

View File

@ -0,0 +1,79 @@
import 'package:flutter/material.dart';
import 'package:pilipala/common/constants.dart';
import 'skeleton.dart';
class MediaBangumiSkeleton extends StatefulWidget {
const MediaBangumiSkeleton({super.key});
@override
State<MediaBangumiSkeleton> createState() => _MediaBangumiSkeletonState();
}
class _MediaBangumiSkeletonState extends State<MediaBangumiSkeleton> {
@override
Widget build(BuildContext context) {
Color bgColor = Theme.of(context).colorScheme.onInverseSurface;
return Skeleton(
child: Padding(
padding: const EdgeInsets.fromLTRB(
StyleString.safeSpace, 7, StyleString.safeSpace, 7),
child: Row(
children: [
Container(
width: 111,
height: 148,
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(6)),
color: bgColor),
),
const SizedBox(width: 10),
SizedBox(
height: 148,
child: Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 200,
height: 20,
margin: const EdgeInsets.only(bottom: 15),
),
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 150,
height: 13,
margin: const EdgeInsets.only(bottom: 5),
),
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 150,
height: 13,
margin: const EdgeInsets.only(bottom: 5),
),
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 150,
height: 13,
),
const Spacer(),
Container(
width: 90,
height: 35,
decoration: BoxDecoration(
borderRadius:
const BorderRadius.all(Radius.circular(20)),
color: Theme.of(context).colorScheme.onInverseSurface,
),
),
],
),
),
),
],
),
),
);
}
}

View File

@ -8,103 +8,86 @@ class VideoCardHSkeleton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Skeleton( return Skeleton(
child: Column( child: Padding(
children: [ padding: const EdgeInsets.fromLTRB(
Padding( StyleString.safeSpace, 7, StyleString.safeSpace, 7),
padding: const EdgeInsets.fromLTRB( child: LayoutBuilder(
StyleString.cardSpace, 7, StyleString.cardSpace, 7), builder: (context, boxConstraints) {
child: LayoutBuilder( double width =
builder: (context, boxConstraints) { (boxConstraints.maxWidth - StyleString.cardSpace * 9) / 2;
double width = return SizedBox(
(boxConstraints.maxWidth - StyleString.cardSpace * 6) / 2; height: width / StyleString.aspectRatio,
return SizedBox( child: Row(
height: width / StyleString.aspectRatio, mainAxisAlignment: MainAxisAlignment.start,
child: Row( crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, children: [
crossAxisAlignment: CrossAxisAlignment.start, AspectRatio(
children: [ aspectRatio: StyleString.aspectRatio,
AspectRatio( child: LayoutBuilder(
aspectRatio: StyleString.aspectRatio, builder: (context, boxConstraints) {
child: LayoutBuilder( return Container(
builder: (context, boxConstraints) { decoration: BoxDecoration(
return Container( color:
decoration: BoxDecoration( Theme.of(context).colorScheme.onInverseSurface,
color: Theme.of(context) borderRadius:
.colorScheme BorderRadius.circular(StyleString.imgRadius.x),
.onInverseSurface, ),
borderRadius: BorderRadius.circular( );
StyleString.imgRadius.x), },
), ),
); ),
}, // VideoContent(videoItem: videoItem)
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 4, 6, 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 200,
height: 11,
margin: const EdgeInsets.only(bottom: 5),
), ),
), Container(
// VideoContent(videoItem: videoItem) color: Theme.of(context).colorScheme.onInverseSurface,
Expanded( width: 150,
child: Padding( height: 13,
padding: const EdgeInsets.fromLTRB(10, 4, 6, 4), ),
child: Column( const Spacer(),
crossAxisAlignment: CrossAxisAlignment.start, Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 100,
height: 13,
margin: const EdgeInsets.only(bottom: 5),
),
Row(
children: [ children: [
Container( Container(
color: Theme.of(context) color: Theme.of(context)
.colorScheme .colorScheme
.onInverseSurface, .onInverseSurface,
width: 200, width: 40,
height: 11, height: 13,
margin: const EdgeInsets.only(bottom: 5), margin: const EdgeInsets.only(right: 8),
), ),
Container( Container(
color: Theme.of(context) color: Theme.of(context)
.colorScheme .colorScheme
.onInverseSurface, .onInverseSurface,
width: 150, width: 40,
height: 13, height: 13,
), ),
const Spacer(),
Container(
color: Theme.of(context)
.colorScheme
.onInverseSurface,
width: 100,
height: 13,
margin: const EdgeInsets.only(bottom: 5),
),
Row(
children: [
Container(
color: Theme.of(context)
.colorScheme
.onInverseSurface,
width: 40,
height: 13,
margin: const EdgeInsets.only(right: 8),
),
Container(
color: Theme.of(context)
.colorScheme
.onInverseSurface,
width: 40,
height: 13,
),
],
)
], ],
), )
)), ],
], ),
), )),
); ],
}, ),
), );
), },
Divider( ),
height: 1,
indent: 8,
endIndent: 12,
color: Theme.of(context).dividerColor.withOpacity(0.08),
)
],
), ),
); );
} }

View File

@ -56,63 +56,53 @@ class VideoCardH extends StatelessWidget {
SmartDialog.showToast(err.toString()); SmartDialog.showToast(err.toString());
} }
}, },
child: Column( child: Padding(
children: [ padding: const EdgeInsets.fromLTRB(
Padding( StyleString.safeSpace, 7, StyleString.safeSpace, 7),
padding: const EdgeInsets.fromLTRB( child: LayoutBuilder(
StyleString.safeSpace, 6, StyleString.safeSpace, 6), builder: (context, boxConstraints) {
child: LayoutBuilder( double width =
builder: (context, boxConstraints) { (boxConstraints.maxWidth - StyleString.cardSpace * 9) / 2;
double width = return SizedBox(
(boxConstraints.maxWidth - StyleString.cardSpace * 9) / 2; height: width / StyleString.aspectRatio,
return SizedBox( child: Row(
height: width / StyleString.aspectRatio, mainAxisAlignment: MainAxisAlignment.start,
child: Row( crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, children: [
crossAxisAlignment: CrossAxisAlignment.start, AspectRatio(
children: [ aspectRatio: StyleString.aspectRatio,
AspectRatio( child: LayoutBuilder(
aspectRatio: StyleString.aspectRatio, builder: (context, boxConstraints) {
child: LayoutBuilder( double maxWidth = boxConstraints.maxWidth;
builder: (context, boxConstraints) { double maxHeight = boxConstraints.maxHeight;
double maxWidth = boxConstraints.maxWidth; return Stack(
double maxHeight = boxConstraints.maxHeight; children: [
return Stack( Hero(
children: [ tag: heroTag,
Hero( child: NetworkImgLayer(
tag: heroTag, src: videoItem.pic,
child: NetworkImgLayer( width: maxWidth,
src: videoItem.pic, height: maxHeight,
width: maxWidth, ),
height: maxHeight, ),
), pBadge(Utils.timeFormat(videoItem.duration!),
), context, null, 6.0, 6.0, null,
pBadge(Utils.timeFormat(videoItem.duration!), type: 'gray'),
context, null, 6.0, 6.0, null, if (videoItem.rcmdReason != null &&
type: 'gray'), videoItem.rcmdReason.content != '')
if (videoItem.rcmdReason != null && pBadge(videoItem.rcmdReason.content, context,
videoItem.rcmdReason.content != '') 6.0, 6.0, null, null),
pBadge(videoItem.rcmdReason.content, ],
context, 6.0, 6.0, null, null), );
], },
); ),
},
),
),
VideoContent(videoItem: videoItem)
],
), ),
); VideoContent(videoItem: videoItem)
}, ],
), ),
), );
// Divider( },
// height: 1, ),
// indent: 8,
// endIndent: 12,
// color: Theme.of(context).dividerColor.withOpacity(0.08),
// )
],
), ),
), ),
); );

View File

@ -17,6 +17,13 @@ class SearchPage extends StatefulWidget {
class _SearchPageState extends State<SearchPage> with RouteAware { class _SearchPageState extends State<SearchPage> with RouteAware {
final SSearchController _searchController = Get.put(SSearchController()); final SSearchController _searchController = Get.put(SSearchController());
late Future? _futureBuilderFuture;
@override
void initState() {
super.initState();
_futureBuilderFuture = _searchController.queryHotSearchList();
}
@override @override
// 返回当前页面时 // 返回当前页面时
@ -159,7 +166,7 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
builder: (context, boxConstraints) { builder: (context, boxConstraints) {
final double width = boxConstraints.maxWidth; final double width = boxConstraints.maxWidth;
return FutureBuilder( return FutureBuilder(
future: _searchController.queryHotSearchList(), future: _futureBuilderFuture,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) { if (snapshot.connectionState == ConnectionState.done) {
Map data = snapshot.data as Map; Map data = snapshot.data as Map;

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/common/skeleton/media_bangumi.dart';
import 'package:pilipala/common/skeleton/video_card_h.dart'; import 'package:pilipala/common/skeleton/video_card_h.dart';
import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/common/widgets/http_error.dart';
import 'package:pilipala/models/common/search_type.dart'; import 'package:pilipala/models/common/search_type.dart';
@ -104,7 +105,18 @@ class _SearchPanelState extends State<SearchPanel>
addRepaintBoundaries: false, addRepaintBoundaries: false,
itemCount: 15, itemCount: 15,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return const VideoCardHSkeleton(); switch (widget.searchType) {
case SearchType.video:
return const VideoCardHSkeleton();
case SearchType.media_bangumi:
return const MediaBangumiSkeleton();
case SearchType.bili_user:
return const VideoCardHSkeleton();
case SearchType.live_room:
return const VideoCardHSkeleton();
default:
return const VideoCardHSkeleton();
}
}, },
); );
} }

View File

@ -6,7 +6,7 @@ import 'package:pilipala/utils/utils.dart';
Widget searchLivePanel(BuildContext context, ctr, list) { Widget searchLivePanel(BuildContext context, ctr, list) {
return Padding( return Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: StyleString.cardSpace, right: StyleString.cardSpace), left: StyleString.safeSpace, right: StyleString.safeSpace),
child: GridView.builder( child: GridView.builder(
primary: false, primary: false,
controller: ctr!.scrollController, controller: ctr!.scrollController,
@ -16,73 +16,82 @@ Widget searchLivePanel(BuildContext context, ctr, list) {
mainAxisSpacing: StyleString.cardSpace + 3, mainAxisSpacing: StyleString.cardSpace + 3,
mainAxisExtent: mainAxisExtent:
MediaQuery.of(context).size.width / 2 / StyleString.aspectRatio + MediaQuery.of(context).size.width / 2 / StyleString.aspectRatio +
65, 60,
), ),
itemCount: list.length, itemCount: list.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
var i = list![index]; return LiveItem(liveItem: list![index]);
return Card(
elevation: 0,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: StyleString.mdRadius,
),
margin: EdgeInsets.zero,
child: InkWell(
onTap: () {},
child: Column(
children: [
ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: StyleString.imgRadius,
topRight: StyleString.imgRadius,
bottomLeft: StyleString.imgRadius,
bottomRight: StyleString.imgRadius,
),
child: AspectRatio(
aspectRatio: StyleString.aspectRatio,
child: LayoutBuilder(builder: (context, boxConstraints) {
double maxWidth = boxConstraints.maxWidth;
double maxHeight = boxConstraints.maxHeight;
return Stack(
children: [
Hero(
tag: Utils.makeHeroTag(i.roomid),
child: NetworkImgLayer(
src: i.cover,
type: 'emote',
width: maxWidth,
height: maxHeight,
),
),
Positioned(
left: 0,
right: 0,
bottom: 0,
child: AnimatedOpacity(
opacity: 1,
duration: const Duration(milliseconds: 200),
child: LiveStat(
online: i.online,
cateName: i.cateName,
),
),
),
],
);
}),
),
),
LiveContent(liveItem: i)
],
),
),
);
}, },
), ),
); );
} }
class LiveItem extends StatelessWidget {
final dynamic liveItem;
const LiveItem({Key? key, required this.liveItem}) : super(key: key);
@override
Widget build(BuildContext context) {
return Card(
elevation: 0,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: StyleString.mdRadius,
),
margin: EdgeInsets.zero,
child: InkWell(
onTap: () {},
child: Column(
children: [
ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: StyleString.imgRadius,
topRight: StyleString.imgRadius,
bottomLeft: StyleString.imgRadius,
bottomRight: StyleString.imgRadius,
),
child: AspectRatio(
aspectRatio: StyleString.aspectRatio,
child: LayoutBuilder(builder: (context, boxConstraints) {
double maxWidth = boxConstraints.maxWidth;
double maxHeight = boxConstraints.maxHeight;
return Stack(
children: [
Hero(
tag: Utils.makeHeroTag(liveItem.roomid),
child: NetworkImgLayer(
src: liveItem.cover,
type: 'emote',
width: maxWidth,
height: maxHeight,
),
),
Positioned(
left: 0,
right: 0,
bottom: 0,
child: AnimatedOpacity(
opacity: 1,
duration: const Duration(milliseconds: 200),
child: LiveStat(
online: liveItem.online,
cateName: liveItem.cateName,
),
),
),
],
);
}),
),
),
LiveContent(liveItem: liveItem)
],
),
),
);
}
}
class LiveContent extends StatelessWidget { class LiveContent extends StatelessWidget {
final dynamic liveItem; final dynamic liveItem;
const LiveContent({Key? key, required this.liveItem}) : super(key: key); const LiveContent({Key? key, required this.liveItem}) : super(key: key);

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/widgets/badge.dart'; import 'package:pilipala/common/widgets/badge.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/http/search.dart'; import 'package:pilipala/http/search.dart';
@ -28,7 +29,8 @@ Widget searchMbangumiPanel(BuildContext context, ctr, list) {
// }); // });
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), padding: const EdgeInsets.fromLTRB(
StyleString.safeSpace, 7, StyleString.safeSpace, 7),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [