feat: 首页,播放页,搜索页,收藏UI

This commit is contained in:
csw 2026-06-29 18:22:02 +08:00
parent 197c3e9b88
commit e59ac2177b
19 changed files with 475 additions and 81 deletions

BIN
assets/pics/liked.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
assets/pics/player_lt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

BIN
assets/pics/unlike.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -3,6 +3,8 @@ import 'package:skywood/global/request/api_const.dart';
import 'package:skywood/global/request/app_request.dart'; import 'package:skywood/global/request/app_request.dart';
import 'package:skywood/global/tool/sky_log.dart'; import 'package:skywood/global/tool/sky_log.dart';
import 'package:skywood/utils/models/drama/skywood_category.dart'; import 'package:skywood/utils/models/drama/skywood_category.dart';
import 'package:skywood/utils/models/drama/skywood_detail.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/models/drama/skywood_home.dart'; import 'package:skywood/utils/models/drama/skywood_home.dart';
class PlayClient { class PlayClient {
@ -23,7 +25,7 @@ class PlayClient {
static Future<List<SkywoodCategory>> getCategoriesList() { static Future<List<SkywoodCategory>> getCategoriesList() {
return AppRequest.get(ApiStringPlay.getCategoriesList).then((value) { return AppRequest.get(ApiStringPlay.getCategoriesList).then((value) {
SkyLog.print('vvvvv: ${value.data}'); // SkyLog.print('vvvvv: ${value.data}');
if (!value.isSuccess) return []; if (!value.isSuccess) return [];
Map<String, dynamic> data = value.data['data']; Map<String, dynamic> data = value.data['data'];
@ -34,8 +36,78 @@ class PlayClient {
// id 28 , // id 28 ,
categoryList = list.map((e) => SkywoodCategory.fromJson(e)).toList(); categoryList = list.map((e) => SkywoodCategory.fromJson(e)).toList();
categoryList.removeWhere((element) => element.id == 28); categoryList.removeWhere((element) => element.id == 28);
categoryList.removeWhere((element) => element.name.length >= 10);
} }
return categoryList; return categoryList;
}); });
} }
// getSearchHots
static Future<List<SkywoodDrama>> getSearchHots() {
return AppRequest.get(ApiStringPlay.getSearchHots).then((value) {
if (value.isSuccess) {
SkyLog.print('getSearchHots: ${value.data}');
List list = parseDataForList(value.data);
return list.map((e) => SkywoodDrama.fromJson(e)).toList();
}
return [];
});
}
//getCollections
static Future<List> getCollections({
int page = 1, int pageSize = 10
}) {
Map<String, dynamic> params = _setPage(page: page, pageSize: pageSize);
return AppRequest.get(ApiStringPlay.getCollections, queryParameters: params).then((value) {
if (value.isSuccess) {
SkyLog.print('getCollections: ${value.data}');
}
return [];
});
}
// getHistory
static Future<List> getHistory({
int page = 1, int pageSize = 10
}) {
Map<String, dynamic> params = _setPage(page: page, pageSize: pageSize);
return AppRequest.get(ApiStringPlay.getHistories, queryParameters: params).then((value) {
if (value.isSuccess) {
SkyLog.print('getHistory: ${value.data}');
}
return [];
});
}
// getVideoDetail
static Future<SkywoodDetail?> getVideoDetail({
required int shortPlayId,
required int shortPlayVideoId,
}) {
Map<String, dynamic> params = {};
params['short_play_id'] = shortPlayId;
params['short_play_video_id'] = shortPlayVideoId;
return AppRequest.get(ApiStringPlay.getVideoDetail, queryParameters: params).then((value) {
if (value.isSuccess) {
SkyLog.print('getVideoDetail: ${value.data}');
}
return null;
});
}
static Map<String, dynamic> _setPage({int page = 1, int pageSize = 10}) {
return {
'current_page': page,
'page_size': pageSize,
};
}
static List parseDataForList(Map<String, dynamic> data) {
Map<String, dynamic> map = data['data'];
List? listData = map['list'];
return listData ?? [];
}
} }

View File

@ -63,9 +63,9 @@ class ApiStringPlay {
static const String getVideoDetail = "/getVideoDetails"; static const String getVideoDetail = "/getVideoDetails";
static const String getDetailsRecommand = "/getDetailsRecommand"; static const String getDetailsRecommand = "/getDetailsRecommand";
// getHomeModules GET /home/all-modules /// getHomeModules GET /home/all-modules
// getRankingList POST /homeRanking body type most_trending/top_searched/new_releases // getRankingList POST /homeRanking body type most_trending/top_searched/new_releases
// getCategoriesList GET /getCategories /// getCategoriesList GET /getCategories
// getCategoriesDetail GET /videoList / + extraParams // getCategoriesDetail GET /videoList / + extraParams
// getWaterflowList POST /newShortPlay + extraParams // getWaterflowList POST /newShortPlay + extraParams
static const String getHomeModules = "/home/all-modules"; static const String getHomeModules = "/home/all-modules";
@ -74,7 +74,7 @@ class ApiStringPlay {
static const String getCategoriesDetail = "/videoList"; static const String getCategoriesDetail = "/videoList";
static const String getWaterflowList = "/newShortPlay"; static const String getWaterflowList = "/newShortPlay";
// getSearchHots GET /search/hots /// getSearchHots GET /search/hots
// getSearch GET /search query: search // getSearch GET /search query: search
// collect POST /collect body: short_play_id, video_id // collect POST /collect body: short_play_id, video_id
// cancelCollect POST /cancelCollect body: short_play_id // cancelCollect POST /cancelCollect body: short_play_id
@ -88,8 +88,8 @@ class ApiStringPlay {
static const String getSearch = "/search"; static const String getSearch = "/search";
static const String collect = "/collect"; static const String collect = "/collect";
static const String cancelCollect = "/cancelCollect"; static const String cancelCollect = "/cancelCollect";
static const String getMyCollections = "/myCollections"; static const String getCollections = "/myCollections";
static const String getMyHistorys = "/myHistorys"; static const String getHistories = "/myHistorys";
static const String getNoticeNum = "/noticeNum"; static const String getNoticeNum = "/noticeNum";
static const String versionControl = "/customer/versionControl"; static const String versionControl = "/customer/versionControl";
static const String getLanguges = "/languges"; static const String getLanguges = "/languges";

View File

@ -23,6 +23,7 @@ class _MainRootState extends State<MainRoot> {
MinePage(), MinePage(),
]; ];
final _pageController = PageController();
final List<_TabBarItem> _items = const [ final List<_TabBarItem> _items = const [
_TabBarItem( _TabBarItem(
selectedIcon: ConstImg.tabHomeSelected, selectedIcon: ConstImg.tabHomeSelected,
@ -52,7 +53,12 @@ class _MainRootState extends State<MainRoot> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
extendBody: true, extendBody: true,
body: IndexedStack(index: _currentIndex, children: _pages), // body: IndexedStack(index: _currentIndex, children: _pages),
body: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
children: _pages,
),
bottomNavigationBar: SafeArea( bottomNavigationBar: SafeArea(
top: false, top: false,
minimum: EdgeInsets.only(bottom: 10.h), minimum: EdgeInsets.only(bottom: 10.h),
@ -113,7 +119,7 @@ class _MainRootState extends State<MainRoot> {
if (_currentIndex == index) { if (_currentIndex == index) {
return; return;
} }
_pageController.jumpToPage(index);
setState(() { setState(() {
_currentIndex = index; _currentIndex = index;
}); });

View File

@ -29,8 +29,8 @@ class _MainRootState extends State<HomePage> {
void initState() { void initState() {
super.initState(); super.initState();
// _getHomeData(); _getHomeData();
// _getDramaCate(); _getDramaCate();
} }
void _getHomeData() { void _getHomeData() {
@ -97,12 +97,14 @@ class _MainRootState extends State<HomePage> {
), ),
_buildTitleImg(ConstImg.homeTitleHotCate), _buildTitleImg(ConstImg.homeTitleHotCate),
SliverPadding( SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 15.w), padding: EdgeInsets.only(left: 15.w, right: 15.w, top: 20.h),
sliver: HomeCateWidget( sliver: SliverToBoxAdapter(
categories: _categories, child: HomeCateWidget(
categories: _categories,
),
), ),
), ),
_buildSpace(height: 100), _buildSpace(height: 20),
], ],
), ),
), ),

View File

@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:skywood/global/client/play_client.dart';
import 'package:skywood/pages/home/players/widget/player_bottom_widget.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/models/drama/skywood_home.dart';
import 'package:skywood/utils/tools/widgets/sky_app_bar.dart';
class DramaDetailPage extends StatefulWidget {
const DramaDetailPage({super.key,
required this.dramaBean,
});
final SkywoodDrama dramaBean;
@override
State<StatefulWidget> createState() {
return _DramaDetailPageState();
}
}
class _DramaDetailPageState extends State<DramaDetailPage> {
@override
void initState() {
super.initState();
// _getDetailDrama();
}
// void _getDetailDrama() {
// PlayClient.getVideoDetail(
// shortPlayId: widget.shortPlayId,
// shortPlayVideoId: widget.shortPlayVideoId
// ).then((value) {});
// }
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: SkyAppBar(
title: widget.dramaBean.name,
backgroundColor: Colors.transparent,
),
body: _bodyWidget(),
);
}
Widget _bodyWidget() {
return Stack(
children: [
SizedBox(width: double.infinity, height: double.infinity),
Positioned(
bottom: 0, left: 0, right: 0,
child: PlayerBottomWidget(),
),
],
);
}
}

View File

@ -0,0 +1,95 @@
import 'package:flutter/material.dart';
import 'package:skywood/main/lib_file.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
class PlayerBottomWidget extends StatefulWidget {
const PlayerBottomWidget({super.key});
@override
State<StatefulWidget> createState() {
return _PlayerBottomWidgetState();
}
}
class _PlayerBottomWidgetState extends State<PlayerBottomWidget> {
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
HelpImg.asset(ConstImg.unlike, width: 40, height: 40),
const SizedBox(height: 24),
Container(
height: 36,
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: Colors.white.withAlpha(30),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
HelpImg.asset(ConstImg.playLt, width: 17, height: 17),
const SizedBox(width: 10),
SkyText(text: 'EP.1', fontSize: 13, color: Colors.white,),
SkyText(text: ' / EP.50', fontSize: 13, color: Colors.white.withAlpha(126)),
],
),
Icon(Icons.arrow_forward_ios, color: Colors.white, size: 13,),
],
),
),
const SizedBox(height: 8),
_buildProgressBar(),
const SizedBox(height: 7),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
SkyText(text: '00:09', fontSize: 13, color: Colors.white),
SkyText(text: ' / 10:20', fontSize: 13, color: Colors.white.withAlpha(126)),
],
),
SkyText(text: 'x1.0', fontSize: 13, color: Colors.white),
],
),
const SizedBox(height: 20),
],
),
);
}
Widget _buildProgressBar() {
return SizedBox(
width: double.infinity, height: 3,
child: SliderTheme(
data: SliderThemeData(
trackHeight: 3, // 3
thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 1),
overlayShape: const RoundSliderOverlayShape(overlayRadius: 3),
activeTrackColor: Colors.white, // =
inactiveTrackColor: Colors.white.withAlpha(126), // =
thumbColor: Colors.white,
overlayColor: Colors.white.withOpacity(0.3),
),
child: Slider(
padding: EdgeInsets.zero,
value: 0.5,
min: 0,
max: 1,
onChanged: (value) {
// _controller.seekTo(Duration(milliseconds: value.toInt()));
},
),
),
);
}
}

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:skywood/global/const/common_color.dart'; import 'package:skywood/global/const/common_color.dart';
import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/home/players/page/drama_detail_page.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart'; import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/tools/sky_time_tool.dart'; import 'package:skywood/utils/tools/sky_time_tool.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart'; import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
@ -91,6 +93,9 @@ class DailyQuestWidget extends StatelessWidget {
), ),
SizedBox(height: 3.h), SizedBox(height: 3.h),
], ],
); ).addInkWell(onTap: () {
HelpNav.to(DramaDetailPage(dramaBean: drama));
});
} }
} }

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:skywood/main/lib_file.dart'; import 'package:skywood/main/lib_file.dart';
import 'package:skywood/utils/models/drama/skywood_category.dart'; import 'package:skywood/utils/models/drama/skywood_category.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
class HomeCateWidget extends StatelessWidget { class HomeCateWidget extends StatelessWidget {
@ -12,15 +13,20 @@ class HomeCateWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliverGrid.builder( return SizedBox(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( height: 270, width: double.infinity,
crossAxisCount: 2, // 🔥 2 child: GridView.builder(
crossAxisSpacing: 10, // scrollDirection: Axis.horizontal,
mainAxisSpacing: 10, // gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.7, // / crossAxisCount: 2, // 🔥 2
), itemBuilder: (context, index) { crossAxisSpacing: 14, //
return _buildCateItem(categories[index], index); mainAxisSpacing: 10, //
} childAspectRatio: 140 / 131.0, // /
),
itemCount: categories.length,
itemBuilder: (context, index) {
return _buildCateItem(categories[index], index);}
),
); );
} }
@ -28,8 +34,69 @@ class HomeCateWidget extends StatelessWidget {
String imgName = index%3 == 0 ? ConstImg.purpleBg : (index%3 == 1 ? ConstImg.yellowBg : ConstImg.redBg); String imgName = index%3 == 0 ? ConstImg.purpleBg : (index%3 == 1 ? ConstImg.yellowBg : ConstImg.redBg);
return Stack( return Stack(
children: [ children: [
HelpImg.asset(imgName, width: 140.w, height: 131.h, fit: BoxFit.cover), HelpImg.asset(imgName, width: 140.w, height: 131.w, fit: BoxFit.fill),
Positioned(
bottom: 24.h, left: 10.w, right: 10.w,
child: _customText(category.name,),
)
], ],
); );
} }
_customText(String text) {
return Text(
text,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: Colors.white, //
fontStyle: FontStyle.italic,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
shadows: [
Shadow(
color: Colors.black, //
offset: Offset(1, 1), //
blurRadius: 0, //
),
Shadow(
color: Colors.black,
offset: Offset(-1, -1),
blurRadius: 0,
),
Shadow(
color: Colors.black,
offset: Offset(1, -1),
blurRadius: 0,
),
Shadow(
color: Colors.black,
offset: Offset(-1, 1),
blurRadius: 0,
),
//
// Shadow(
// color: Colors.black,
// offset: Offset(2, 0),
// blurRadius: 0,
// ),
// Shadow(
// color: Colors.black,
// offset: Offset(-2, 0),
// blurRadius: 0,
// ),
// Shadow(
// color: Colors.black,
// offset: Offset(0, 2),
// blurRadius: 0,
// ),
// Shadow(
// color: Colors.black,
// offset: Offset(0, -2),
// blurRadius: 0,
// ),
],
),
);
}
} }

View File

@ -34,7 +34,7 @@ class HotCartridgeWidget extends StatelessWidget {
), ),
Positioned( Positioned(
top: 1, left: 5.w, right: 5.w, top: 1, left: 5.w, right: 5.w,
child: HelpImg.network(drama.imageUrl, width: 100.w, height: 130.h), child: HelpImg.network(drama.imageUrl, width: 100.w, height: 130.h, fit: BoxFit.cover),
), ),
HelpImg.asset(index<3?ConstImg.hotBg1:ConstImg.hotBg2, width: 110.w, height: 174.h) HelpImg.asset(index<3?ConstImg.hotBg1:ConstImg.hotBg2, width: 110.w, height: 174.h)
], ],

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:skywood/global/client/play_client.dart';
import 'package:skywood/main/lib_file.dart'; import 'package:skywood/main/lib_file.dart';
class CollectionPage extends StatefulWidget { class CollectionPage extends StatefulWidget {
@ -13,6 +14,19 @@ class CollectionPage extends StatefulWidget {
class _CollectionPageState extends State<CollectionPage> { class _CollectionPageState extends State<CollectionPage> {
@override
void initState() {
// TODO: implement initState
super.initState();
_getCollection();
}
void _getCollection() {
PlayClient.getCollections().then((value) {
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GridView.builder( return GridView.builder(

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:skywood/global/client/play_client.dart';
import 'package:skywood/main/lib_file.dart'; import 'package:skywood/main/lib_file.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart'; import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
@ -14,6 +15,16 @@ class PlayLogPage extends StatefulWidget {
class _CollectionPageState extends State<PlayLogPage> { class _CollectionPageState extends State<PlayLogPage> {
@override
void initState() {
super.initState();
_getHistory();
}
void _getHistory() {
PlayClient.getHistory().then((value) {});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView.separated( return ListView.separated(

View File

@ -1,10 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:skywood/global/client/play_client.dart';
import 'package:skywood/main/lib_file.dart'; import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/search/page/result_page.dart'; import 'package:skywood/pages/search/page/result_page.dart';
import 'package:skywood/pages/search/widget/search_util.dart'; import 'package:skywood/pages/search/widget/search_util.dart';
import 'package:skywood/pages/search/widget/search_view.dart'; import 'package:skywood/pages/search/widget/search_view.dart';
import 'package:skywood/pages/widgets/pixel_widgets.dart'; import 'package:skywood/pages/widgets/pixel_widgets.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/tools/help_nav.dart'; import 'package:skywood/utils/tools/help_nav.dart';
import 'package:skywood/utils/tools/sky_time_tool.dart';
import 'package:skywood/utils/tools/widgets/sky_app_bar.dart'; import 'package:skywood/utils/tools/widgets/sky_app_bar.dart';
import 'package:skywood/utils/tools/widgets/sky_text_field.dart'; import 'package:skywood/utils/tools/widgets/sky_text_field.dart';
@ -33,6 +36,7 @@ class _MainRootState extends State<SearchPage> {
'Who Dared Touch My Bride', 'Who Dared Touch My Bride',
'Famous Families Fled', 'Famous Families Fled',
]; ];
List<SkywoodDrama> _searchHots = [];
Future<void> _loadSearchHistory() async { Future<void> _loadSearchHistory() async {
final list = await SearchUtil.getSearchList(); final list = await SearchUtil.getSearchList();
@ -61,6 +65,16 @@ class _MainRootState extends State<SearchPage> {
super.initState(); super.initState();
_loadSearchHistory(); _loadSearchHistory();
_getSearchHots();
}
void _getSearchHots() {
PlayClient.getSearchHots().then((value) {
print('object: ${value.length}');
setState(() {
_searchHots = value;
});
});
} }
@override @override
@ -129,76 +143,119 @@ class _MainRootState extends State<SearchPage> {
} }
Widget _buildTrendingList() { Widget _buildTrendingList() {
if (_searchHots.isEmpty) return const SizedBox.shrink();
// 4
final List<List<SkywoodDrama>> groupedData = [];
for (int i = 0; i < _searchHots.length; i += 4) {
final end = (i + 4 > _searchHots.length) ? _searchHots.length : i + 4;
groupedData.add(_searchHots.sublist(i, end));
}
return SizedBox( return SizedBox(
height: 446.h, height: 114 * 4 + 20, // 104 * 4 + 10 * 3
child: SingleChildScrollView( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
padding: EdgeInsets.symmetric(horizontal: 15.w), padding: EdgeInsets.symmetric(horizontal: 15.w),
child: Wrap( itemBuilder: (context, index) {
direction: Axis.vertical, final group = groupedData[index];
spacing: 10.h, return _buildGroup(group);
runSpacing: 10.w, },
children: _titles separatorBuilder: (context, index) => SizedBox(width: 10.w),
.map((title) => _TrendingItem(title: title)) itemCount: groupedData.length,
.toList(),
),
), ),
); );
} }
/// 4
Widget _buildGroup(List<SkywoodDrama> group) {
return SizedBox(
width: 236,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: group.map((drama) {
return _TrendingItem(drama: drama);
}).toList(),
),
);
}
// Widget _buildTrendingList() {
// return Container(
// height: 114 * 4, width: AppScreen.screenWidth,
// color: Colors.green,
// child: GridView.builder(
// padding: EdgeInsets.only(left: 15.w),
// scrollDirection: Axis.horizontal,
// gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: 4, // 4
// crossAxisSpacing: 10, //
// mainAxisSpacing: 10, //
// childAspectRatio: 236 / 104.0, // /
// ),
// itemCount: _searchHots.length,
// itemBuilder: (context, index) {
// final drama = _searchHots[index];
// return Container(width: 236, height: 104, color: index%2==0 ? Colors.orangeAccent : Colors.redAccent,);
// return _TrendingItem(drama: drama);
// }
// ),
// );
// }
} }
class _TrendingItem extends StatelessWidget { class _TrendingItem extends StatelessWidget {
const _TrendingItem({required this.title}); const _TrendingItem({required this.drama});
final String title; final SkywoodDrama drama;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return Container(
width: 236.w, margin: EdgeInsets.only(bottom: 10),
height: 104.h, // width: 236.w,
// height: 104.w,
child: Row( child: Row(
children: [ children: [
const PosterImage(
width: 80, HelpImg.network(drama.imageUrl, width: 80, height: 104, fit: BoxFit.cover),
height: 104, SizedBox(width: 8),
borderRadius: 4,
showBorder: false,
),
SizedBox(width: 8.w),
Expanded( Expanded(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(vertical: 10.h), padding: EdgeInsets.symmetric(vertical: 10),
child: Column( child: SizedBox(
crossAxisAlignment: CrossAxisAlignment.start, height: 84,
mainAxisAlignment: MainAxisAlignment.spaceBetween, child: Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
Text( mainAxisAlignment: MainAxisAlignment.spaceBetween,
title, children: [
maxLines: 2, Text(
overflow: TextOverflow.ellipsis, drama.name,
style: TextStyle( maxLines: 2,
color: CommonColor.black, overflow: TextOverflow.ellipsis,
fontSize: 13.sp, style: TextStyle(
fontWeight: FontWeight.bold, color: CommonColor.black,
height: 1.2, fontSize: 13.sp,
), fontWeight: FontWeight.bold,
), height: 1.2,
Row(
children: [
HelpImg.asset(ConstImg.hot, width: 15.w, height: 15.w),
SizedBox(width: 2.w),
Text(
'17.3K',
style: TextStyle(
color: const Color(0x80000000),
fontSize: 13.w,
height: 1,
),
), ),
], ),
), Spacer(),
], Row(
children: [
HelpImg.asset(ConstImg.hot, width: 15.w, height: 15.w),
SizedBox(width: 2.w),
Text(
SkyTimeTool.formatNum(drama.watchTotal, unit: 'w'),
style: TextStyle(
color: const Color(0x80000000),
fontSize: 13.w,
height: 1,
),
),
],
),
],
),
), ),
), ),
), ),

View File

@ -58,6 +58,9 @@ class ConstImg {
static const String likeSelectedBg = "assets/pics/like_selected_bg.png"; static const String likeSelectedBg = "assets/pics/like_selected_bg.png";
static const String likeUnselectBg = "assets/pics/like_unselect_bg.png"; static const String likeUnselectBg = "assets/pics/like_unselect_bg.png";
static const String continueWatch = "assets/pics/continue_watch.png"; static const String continueWatch = "assets/pics/continue_watch.png";
static const String playLt = "assets/pics/player_lt.png";
static const String liked = "assets/pics/liked.png";
static const String unlike = "assets/pics/unlike.png";
// nodata // nodata

View File

@ -16,6 +16,7 @@ class SkyTimeTool {
num value, { num value, {
int decimalDigits = 1, int decimalDigits = 1,
String separator = ',', String separator = ',',
String unit = 'K',
}) { }) {
String removeTrailingZeros(String str) { String removeTrailingZeros(String str) {
if (str.contains('.')) { if (str.contains('.')) {
@ -43,8 +44,9 @@ class SkyTimeTool {
if (value < 1000) { if (value < 1000) {
return addSeparator(value.toStringAsFixed(0)); return addSeparator(value.toStringAsFixed(0));
} else if (value < 1000000) { } else if (value < 1000000) {
final formatted = (value / 10000).toStringAsFixed(decimalDigits); int mu = unit=='w' ? 10000 : 1000;
return '${removeTrailingZeros(formatted)}w'; final formatted = (value / mu).toStringAsFixed(decimalDigits);
return '${removeTrailingZeros(formatted)}$unit';
} else { } else {
final formatted = (value / 1000000).toStringAsFixed(decimalDigits); final formatted = (value / 1000000).toStringAsFixed(decimalDigits);
return '${removeTrailingZeros(formatted)}m'; return '${removeTrailingZeros(formatted)}m';