feat: 页面优化

This commit is contained in:
guozhigq
2023-08-14 10:14:59 +08:00
parent 17b02d9ae9
commit cf81897d27
18 changed files with 494 additions and 402 deletions

View File

@ -14,7 +14,7 @@ class VideoCardHSkeleton extends StatelessWidget {
child: LayoutBuilder(
builder: (context, boxConstraints) {
double width =
(boxConstraints.maxWidth - StyleString.cardSpace * 9) / 2;
(boxConstraints.maxWidth - StyleString.cardSpace * 6) / 2;
return SizedBox(
height: width / StyleString.aspectRatio,
child: Row(

View File

@ -57,7 +57,7 @@ class VideoCardH extends StatelessWidget {
child: LayoutBuilder(
builder: (context, boxConstraints) {
double width =
(boxConstraints.maxWidth - StyleString.cardSpace * 9) / 2;
(boxConstraints.maxWidth - StyleString.cardSpace * 6) / 2;
return SizedBox(
height: width / StyleString.aspectRatio,
child: Row(
@ -83,10 +83,10 @@ class VideoCardH extends StatelessWidget {
pBadge(Utils.timeFormat(videoItem.duration!),
context, null, 6.0, 6.0, null,
type: 'gray'),
if (videoItem.rcmdReason != null &&
videoItem.rcmdReason.content != '')
pBadge(videoItem.rcmdReason.content, context,
6.0, 6.0, null, null),
// if (videoItem.rcmdReason != null &&
// videoItem.rcmdReason.content != '')
// pBadge(videoItem.rcmdReason.content, context,
// 6.0, 6.0, null, null),
],
);
},
@ -124,7 +124,6 @@ class VideoContent extends StatelessWidget {
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500,
letterSpacing: 0.3,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
@ -198,24 +197,59 @@ class VideoContent extends StatelessWidget {
// color: Theme.of(context).colorScheme.outline),
// )
const Spacer(),
// 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,
// ),
// ),
// ),
SizedBox(
width: 20,
height: 20,
child: IconButton(
width: 24,
height: 24,
child: PopupMenuButton<String>(
padding: EdgeInsets.zero,
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,
),
position: PopupMenuPosition.under,
// constraints: const BoxConstraints(maxHeight: 35),
onSelected: (String type) {},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<String>>[
PopupMenuItem<String>(
onTap: () async {
var res =
await UserHttp.toViewLater(bvid: videoItem.bvid);
SmartDialog.showToast(res['msg']);
},
value: 'pause',
height: 35,
child: const Row(
children: [
Icon(Icons.watch_later_outlined, size: 16),
SizedBox(width: 6),
Text('稍后再看', style: TextStyle(fontSize: 13))
],
),
),
],
),
),
],

View File

@ -5,7 +5,6 @@ import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/widgets/stat/danmu.dart';
import 'package:pilipala/common/widgets/stat/view.dart';
import 'package:pilipala/http/user.dart';
import 'package:pilipala/pages/rcmd/index.dart';
import 'package:pilipala/utils/id_utils.dart';
import 'package:pilipala/utils/utils.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
@ -106,17 +105,13 @@ class VideoCardV extends StatelessWidget {
}
class VideoContent extends StatelessWidget {
// ignore: prefer_typing_uninitialized_variables
final videoItem;
final dynamic videoItem;
const VideoContent({Key? key, required this.videoItem}) : 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),
padding: const EdgeInsets.fromLTRB(4, 8, 0, 3),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -124,12 +119,8 @@ class VideoContent extends StatelessWidget {
Text(
videoItem.title,
textAlign: TextAlign.start,
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500,
letterSpacing: 0.3,
),
maxLines: Get.find<RcmdController>().crossAxisCount,
style: const TextStyle(fontSize: 13),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
@ -181,38 +172,90 @@ class VideoContent extends StatelessWidget {
}),
),
SizedBox(
width: 20,
height: 20,
child: IconButton(
width: 24,
height: 24,
child: PopupMenuButton<String>(
padding: EdgeInsets.zero,
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,
),
position: PopupMenuPosition.under,
// constraints: const BoxConstraints(maxHeight: 35),
onSelected: (String type) {},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<String>>[
PopupMenuItem<String>(
onTap: () async {
var res =
await UserHttp.toViewLater(bvid: videoItem.bvid);
SmartDialog.showToast(res['msg']);
},
value: 'pause',
height: 35,
child: const Row(
children: [
Icon(Icons.watch_later_outlined, size: 16),
SizedBox(width: 6),
Text('稍后再看', style: TextStyle(fontSize: 13))
],
),
),
],
),
),
],
),
// Row(
// children: [
// const SizedBox(width: 1),
// StatView(
// theme: 'black',
// theme: 'gray',
// view: videoItem.stat.view,
// ),
// const SizedBox(width: 6),
// const SizedBox(width: 10),
// StatDanMu(
// theme: 'black',
// theme: 'gray',
// danmu: videoItem.stat.danmaku,
// ),
// const Spacer(),
// SizedBox(
// width: 24,
// height: 24,
// child: PopupMenuButton<String>(
// padding: EdgeInsets.zero,
// tooltip: '稍后再看',
// icon: Icon(
// Icons.more_vert_outlined,
// color: Theme.of(context).colorScheme.outline,
// size: 14,
// ),
// position: PopupMenuPosition.under,
// // constraints: const BoxConstraints(maxHeight: 35),
// onSelected: (String type) {},
// itemBuilder: (BuildContext context) =>
// <PopupMenuEntry<String>>[
// PopupMenuItem<String>(
// onTap: () async {
// var res =
// await UserHttp.toViewLater(bvid: videoItem.bvid);
// SmartDialog.showToast(res['msg']);
// },
// value: 'pause',
// height: 35,
// child: const Row(
// children: [
// Icon(Icons.watch_later_outlined, size: 16),
// SizedBox(width: 6),
// Text('稍后再看', style: TextStyle(fontSize: 13))
// ],
// ),
// ),
// ],
// ),
// ),
// ],
// ),
],
@ -237,7 +280,7 @@ class VideoStat extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 45,
height: 48,
padding: const EdgeInsets.only(top: 22, left: 6, right: 6),
decoration: const BoxDecoration(
gradient: LinearGradient(

View File

@ -58,14 +58,7 @@ class _BangumiPageState extends State<BangumiPage>
@override
Widget build(BuildContext context) {
super.build(context);
return Container(
clipBehavior: Clip.hardEdge,
margin: const EdgeInsets.only(
left: StyleString.safeSpace, right: StyleString.safeSpace),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(StyleString.imgRadius),
),
child: RefreshIndicator(
return RefreshIndicator(
onRefresh: () async {
await _bangumidController.queryBangumiListFeed(type: 'init');
return _bangumidController.queryBangumiFollow();
@ -80,8 +73,8 @@ class _BangumiPageState extends State<BangumiPage>
child: Column(
children: [
Padding(
padding:
const EdgeInsets.only(top: 10, bottom: 10, left: 6),
padding: const EdgeInsets.only(
top: StyleString.safeSpace, bottom: 10, left: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -93,7 +86,7 @@ class _BangumiPageState extends State<BangumiPage>
),
),
SizedBox(
height: 254,
height: 258,
child: FutureBuilder(
future: _bangumidController.queryBangumiFollow(),
builder: (context, snapshot) {
@ -111,7 +104,8 @@ class _BangumiPageState extends State<BangumiPage>
width: Get.size.width / 3,
height: 254,
margin: EdgeInsets.only(
right: index <
left: StyleString.safeSpace,
right: index ==
_bangumidController
.bangumiFollowList
.length -
@ -142,7 +136,7 @@ class _BangumiPageState extends State<BangumiPage>
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(top: 10, bottom: 10, left: 6),
padding: const EdgeInsets.only(top: 10, bottom: 10, left: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -155,15 +149,16 @@ class _BangumiPageState extends State<BangumiPage>
),
),
SliverPadding(
padding: EdgeInsets.zero,
padding: const EdgeInsets.fromLTRB(
StyleString.safeSpace, 0, StyleString.safeSpace, 0),
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));
return Obx(() => contentGrid(
_bangumidController, _bangumidController.bangumiList));
} else {
return HttpError(
errMsg: data['msg'],
@ -179,7 +174,6 @@ class _BangumiPageState extends State<BangumiPage>
const LoadingMore()
],
),
),
);
}

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/http/index.dart';
import 'package:pilipala/models/common/tab_type.dart';
import 'package:pilipala/utils/storage.dart';
@ -12,7 +11,6 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
late TabController tabController;
late List tabsCtrList;
late List<Widget> tabsPageList;
RxString defaultSearch = '输入关键词搜索'.obs;
Box user = GStrorage.user;
RxBool userLogin = false.obs;
RxString userFace = ''.obs;
@ -21,7 +19,6 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
void onInit() {
super.onInit();
searchDefault();
userLogin.value = user.get(UserBoxKey.userLogin) ?? false;
userFace.value = user.get(UserBoxKey.userFace) ?? '';
@ -49,13 +46,6 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
ctr().animateToTop();
}
void searchDefault() async {
var res = await Request().get(Api.searchDefault);
if (res.data['code'] == 0) {
defaultSearch.value = res.data['data']['name'];
}
}
// 更新登录状态
void updateLoginStatus(val) {
userLogin.value = val ?? false;

View File

@ -1,12 +1,9 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/pages/bangumi/index.dart';
import 'package:pilipala/pages/hot/index.dart';
import 'package:pilipala/pages/live/index.dart';
import 'package:pilipala/pages/main/index.dart';
import 'package:pilipala/pages/mine/index.dart';
import 'package:pilipala/pages/rcmd/index.dart';
import 'package:pilipala/pages/search/index.dart';
import 'package:pilipala/utils/feed_back.dart';
import './controller.dart';
@ -53,49 +50,21 @@ class _HomePageState extends State<HomePage>
ctr: _homeController,
callback: showUserBottonSheet,
),
Padding(
padding: const EdgeInsets.only(left: 12, right: 12, bottom: 4),
child: Theme(
data: ThemeData(
splashColor: Colors.transparent, // 点击时的水波纹颜色设置为透明
highlightColor: Colors.transparent, // 点击时的背景高亮颜色设置为透明
),
const SizedBox(height: 8),
SizedBox(
width: double.infinity,
height: 42,
child: Align(
alignment: Alignment.center,
child: TabBar(
controller: _homeController.tabController,
tabs: [
for (var i in _homeController.tabs) Tab(text: i['label'])
],
isScrollable: true,
indicatorWeight: 0,
indicatorPadding: const EdgeInsets.only(
top: 37, left: 18, right: 18, bottom: 6),
indicatorColor: Colors.black,
indicator: BoxDecoration(
gradient: RadialGradient(
center: Alignment.centerLeft,
radius: 20.00,
colors: [
Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.background,
],
),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(4),
topRight: Radius.circular(2),
bottomLeft: Radius.circular(2),
bottomRight: Radius.circular(4),
),
),
indicatorSize: TabBarIndicatorSize.tab,
labelColor: Theme.of(context).colorScheme.primary,
labelStyle:
const TextStyle(fontSize: 13, fontWeight: FontWeight.bold),
dividerColor: Colors.transparent,
unselectedLabelStyle: TextStyle(
color: Theme.of(context).colorScheme.outline,
fontWeight: FontWeight.normal,
),
unselectedLabelColor: Theme.of(context).colorScheme.outline,
enableFeedback: true,
splashBorderRadius: BorderRadius.circular(10),
onTap: (value) {
feedBack();
if (_homeController.initialIndex == value) {
@ -141,83 +110,52 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
stream: stream,
initialData: true,
builder: (context, AsyncSnapshot snapshot) {
return ClipRect(
clipBehavior: Clip.hardEdge,
child: AnimatedOpacity(
return AnimatedOpacity(
opacity: snapshot.data ? 1 : 0,
duration: const Duration(milliseconds: 300),
child: AnimatedContainer(
curve: Curves.linear,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOutCubicEmphasized,
duration: const Duration(milliseconds: 500),
height: snapshot.data
? MediaQuery.of(context).padding.top + 42
? MediaQuery.of(context).padding.top + 52
: MediaQuery.of(context).padding.top,
child: Container(
padding: EdgeInsets.only(
left: 12,
right: 12,
left: 20,
right: 20,
bottom: 0,
top: MediaQuery.of(context).padding.top,
),
child: Row(children: [
Image.asset(
'assets/images/logo/logo_android_2.png',
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(width: 4),
Expanded(
child: GestureDetector(
onTap: () {
Get.toNamed('/search',
parameters: {'hintText': ctr!.defaultSearch.value});
},
child: Container(
width: 250,
height: 40,
clipBehavior: Clip.hardEdge,
padding: const EdgeInsets.only(left: 12, right: 22),
decoration: BoxDecoration(
borderRadius:
const BorderRadius.all(Radius.circular(25)),
color: Theme.of(context).colorScheme.onInverseSurface,
top: MediaQuery.of(context).padding.top + 4,
),
child: Row(
children: [
Icon(
Icons.search_outlined,
size: 21,
color: Theme.of(context).colorScheme.outline,
),
const SizedBox(width: 6),
Expanded(
child: Obx(
() => Text(
ctr!.defaultSearch.value,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Theme.of(context)
.colorScheme
.outline),
),
),
),
],
),
),
),
),
const Expanded(child: SearchPage()),
const SizedBox(width: 10),
Obx(
() => ctr!.userLogin.value
? GestureDetector(
onTap: () => callback!(),
child: NetworkImgLayer(
? Stack(
children: [
NetworkImgLayer(
type: 'avatar',
width: 38,
height: 38,
width: 34,
height: 34,
src: ctr!.userFace.value,
),
Positioned.fill(
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () => callback!(),
splashColor: Theme.of(context)
.colorScheme
.primaryContainer
.withOpacity(0.3),
borderRadius: const BorderRadius.all(
Radius.circular(50),
),
),
),
)
],
)
: SizedBox(
width: 38,
@ -242,7 +180,7 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
),
),
),
]),
],
),
),
),

View File

@ -3,6 +3,7 @@ import 'dart:async';
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/animated_dialog.dart';
import 'package:pilipala/common/widgets/overlay_pop.dart';
import 'package:pilipala/common/skeleton/video_card_h.dart';
@ -59,14 +60,17 @@ class _HotPageState extends State<HotPage> with AutomaticKeepAliveClientMixin {
super.build(context);
return Scaffold(
body: RefreshIndicator(
displacement: kToolbarHeight + MediaQuery.of(context).padding.top,
onRefresh: () async {
return await _hotController.onRefresh();
},
child: CustomScrollView(
controller: _hotController.scrollController,
slivers: [
FutureBuilder(
SliverPadding(
// 单列布局 EdgeInsets.zero
padding:
const EdgeInsets.fromLTRB(0, StyleString.safeSpace - 5, 0, 0),
sliver: FutureBuilder(
future: _futureBuilderFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
@ -74,7 +78,8 @@ class _HotPageState extends State<HotPage> with AutomaticKeepAliveClientMixin {
if (data['status']) {
return Obx(
() => SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
delegate:
SliverChildBuilderDelegate((context, index) {
return VideoCardH(
videoItem: _hotController.videoList[index],
longPress: () {
@ -106,6 +111,7 @@ class _HotPageState extends State<HotPage> with AutomaticKeepAliveClientMixin {
}
},
),
),
SliverToBoxAdapter(
child: SizedBox(
height: MediaQuery.of(context).padding.bottom + 10,

View File

@ -70,7 +70,8 @@ class _LivePageState extends State<LivePage> {
slivers: [
SliverPadding(
// 单列布局 EdgeInsets.zero
padding: EdgeInsets.zero,
padding:
const EdgeInsets.fromLTRB(0, StyleString.safeSpace, 0, 0),
sliver: FutureBuilder(
future: _liveController.queryLiveList('init'),
builder: (context, snapshot) {
@ -118,13 +119,13 @@ class _LivePageState extends State<LivePage> {
return SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// 行间距
mainAxisSpacing: StyleString.cardSpace + 2,
mainAxisSpacing: StyleString.cardSpace + 4,
// 列间距
crossAxisSpacing: StyleString.cardSpace + 3,
crossAxisSpacing: StyleString.cardSpace + 4,
// 列数
crossAxisCount: ctr.crossAxisCount,
mainAxisExtent:
Get.size.width / ctr.crossAxisCount / StyleString.aspectRatio + 60,
Get.size.width / ctr.crossAxisCount / StyleString.aspectRatio + 64,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {

View File

@ -103,7 +103,7 @@ class LiveContent extends StatelessWidget {
return Expanded(
child: Padding(
// 多列
padding: const EdgeInsets.fromLTRB(4, 5, 6, 6),
padding: const EdgeInsets.fromLTRB(4, 8, 0, 6),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -154,7 +154,7 @@ class VideoStat extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 45,
height: 50,
padding: const EdgeInsets.only(top: 22, left: 10, right: 10),
decoration: const BoxDecoration(
gradient: LinearGradient(

View File

@ -15,23 +15,35 @@ class MainController extends GetxController {
RxList navigationBars = [
{
'icon': const Icon(
Icons.motion_photos_on_outlined,
Icons.favorite_outline,
size: 21,
),
'label': "推荐",
'selectIcon': const Icon(
Icons.favorite,
size: 21,
),
'label': "首页",
},
{
'icon': const Icon(
Icons.bolt,
Icons.motion_photos_on_outlined,
size: 21,
),
'selectIcon': const Icon(
Icons.motion_photos_on,
size: 21,
),
'label': "动态",
},
{
'icon': const Icon(
Icons.folder_open_outlined,
Icons.folder_outlined,
size: 20,
),
'selectIcon': const Icon(
Icons.folder,
size: 21,
),
'label': "媒体库",
}
].obs;

View File

@ -135,21 +135,17 @@ class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
initialData: true,
builder: (context, AsyncSnapshot snapshot) {
return AnimatedSlide(
curve: Curves.linear,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOutCubicEmphasized,
duration: const Duration(milliseconds: 1000),
offset: Offset(0, snapshot.data ? 0 : 1),
child: BottomNavigationBar(
currentIndex: selectedIndex,
// type: BottomNavigationBarType.shifting,
selectedItemColor: Theme.of(context).colorScheme.primary,
unselectedItemColor:
Theme.of(context).colorScheme.outline.withOpacity(0.5),
selectedFontSize: 12.4,
onTap: (value) => setIndex(value),
items: [
child: NavigationBar(
onDestinationSelected: (value) => setIndex(value),
selectedIndex: selectedIndex,
destinations: <Widget>[
..._mainController.navigationBars.map((e) {
return BottomNavigationBarItem(
return NavigationDestination(
icon: e['icon'],
selectedIcon: e['selectIcon'],
label: e['label'],
);
}).toList(),

View File

@ -77,7 +77,7 @@ class _RcmdPageState extends State<RcmdPage>
// 单列布局 EdgeInsets.zero
padding: _rcmdController.crossAxisCount == 1
? EdgeInsets.zero
: const EdgeInsets.fromLTRB(0, 0, 0, 0),
: const EdgeInsets.fromLTRB(0, StyleString.safeSpace, 0, 0),
sliver: FutureBuilder(
future: _rcmdController.queryRcmdFeed('init'),
builder: (context, snapshot) {
@ -124,13 +124,13 @@ class _RcmdPageState extends State<RcmdPage>
return SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// 行间距
mainAxisSpacing: StyleString.cardSpace + 2,
mainAxisSpacing: StyleString.cardSpace + 4,
// 列间距
crossAxisSpacing: StyleString.cardSpace + 3,
crossAxisSpacing: StyleString.cardSpace + 4,
// 列数
crossAxisCount: ctr.crossAxisCount,
mainAxisExtent:
Get.size.width / ctr.crossAxisCount / StyleString.aspectRatio + 60,
Get.size.width / ctr.crossAxisCount / StyleString.aspectRatio + 64,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/http/index.dart';
import 'package:pilipala/http/search.dart';
import 'package:pilipala/models/search/hot.dart';
import 'package:pilipala/models/search/suggest.dart';
@ -20,10 +21,12 @@ class SSearchController extends GetxController {
final _debouncer =
Debouncer(delay: const Duration(milliseconds: 200)); // 设置延迟时间
String hintText = '搜索';
RxString defaultSearch = '输入关键词搜索'.obs;
@override
void onInit() {
super.onInit();
searchDefault();
if (hotKeyword.get('cacheList') != null &&
hotKeyword.get('cacheList').isNotEmpty) {
List<HotSearchItem> list = [];
@ -121,4 +124,12 @@ class SSearchController extends GetxController {
historyList.refresh();
histiryWord.put('cacheList', []);
}
void searchDefault() async {
var res = await Request().get(Api.searchDefault);
if (res.data['code'] == 0) {
searchKeyWord.value =
hintText = defaultSearch.value = res.data['data']['name'];
}
}
}

View File

@ -1,5 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:animations/animations.dart';
import 'package:get/get.dart';
import 'package:pilipala/common/widgets/http_error.dart';
import 'controller.dart';
@ -41,6 +42,60 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
@override
Widget build(BuildContext context) {
return OpenContainer(
closedElevation: 0,
openElevation: 0,
openColor: Theme.of(context).colorScheme.background,
middleColor: Theme.of(context).colorScheme.background,
closedColor: Theme.of(context).colorScheme.background,
closedShape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(30.0))),
openShape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(30.0))),
closedBuilder: (BuildContext context, VoidCallback openContainer) {
return Container(
width: 250,
height: 44,
clipBehavior: Clip.hardEdge,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(25)),
),
child: Material(
color:
Theme.of(context).colorScheme.secondaryContainer.withAlpha(115),
child: InkWell(
splashColor: Theme.of(context)
.colorScheme
.primaryContainer
.withOpacity(0.3),
onTap: openContainer,
child: Row(
children: [
const SizedBox(width: 14),
Icon(
Icons.search_outlined,
color: Theme.of(context).colorScheme.onSecondaryContainer,
),
const SizedBox(width: 10),
Expanded(
child: Obx(
() => Text(
_searchController.defaultSearch.value,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Theme.of(context).colorScheme.outline,
),
),
),
),
],
),
),
),
);
},
openBuilder: (BuildContext context, VoidCallback _) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
@ -97,6 +152,8 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
),
),
);
},
);
}
Widget _searchSuggest() {

View File

@ -105,7 +105,8 @@ class _FavPanelState extends State<FavPanel> {
left: 20,
right: 20,
top: 12,
bottom: MediaQuery.of(context).padding.bottom),
bottom: MediaQuery.of(context).padding.bottom + 12,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [

View File

@ -31,6 +31,10 @@ class GStrorage {
localCache = await Hive.openBox('localCache');
// 设置
setting = await Hive.openBox('setting');
// 热搜关键词
hotKeyword = await Hive.openBox('hotKeyword');
// 搜索历史
historyword = await Hive.openBox('historyWord');
}
static regAdapter() {
@ -45,10 +49,6 @@ class GStrorage {
}
static Future<void> lazyInit() async {
// 热搜关键词
hotKeyword = await Hive.openBox('hotKeyword');
// 搜索历史
historyword = await Hive.openBox('historyWord');
// 视频设置
video = await Hive.openBox('video');
}

View File

@ -17,6 +17,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.13.0"
animations:
dependency: "direct main"
description:
name: animations
sha256: fe8a6bdca435f718bb1dc8a11661b2c22504c6da40ef934cee8327ed77934164
url: "https://pub.dev"
source: hosted
version: "2.0.7"
archive:
dependency: transitive
description:

View File

@ -107,6 +107,7 @@ dependencies:
universal_platform: ^1.0.0+1
# 进度条
audio_video_progress_bar: ^1.0.1
animations: ^2.0.7
# auto_orientation: ^2.3.1
dev_dependencies: