feat: 整体常用控件封装,常用工具类。首页数据对接
This commit is contained in:
1 parent
d90d023e85
commit
fbcd33ea2b
50 files changed
+4558
-264
No files matched your search
@@ -0,0 +1,36 @@
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:skywood/global/client/user_client.dart';
|
||||
import 'package:skywood/main/main_root.dart';
|
||||
import 'package:skywood/utils/tools/help_nav.dart';
|
||||
import 'package:skywood/utils/tools/token_manage.dart';
|
||||
|
||||
class UserController extends GetxController {
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
|
||||
// _userRegister();
|
||||
}
|
||||
|
||||
void _userRegister() async {
|
||||
// 先拿token没有的话去注册
|
||||
final tm = TokenManager();
|
||||
String token = tm.get();
|
||||
print('tokkkkkk: $token');
|
||||
if (token.isNotEmpty) {
|
||||
// 成功后去到主页面
|
||||
print('object去主页面');
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
HelpNav.off(MainRoot());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
final res = await UserClient.register();
|
||||
if (res != null) {
|
||||
tm.save(res.token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:skywood/global/client/play_client.dart';
|
||||
import 'package:skywood/global/client/user_client.dart';
|
||||
import 'package:skywood/main/lib_file.dart';
|
||||
import 'package:skywood/pages/home/widgets/daily_quest_widget.dart';
|
||||
import 'package:skywood/pages/widgets/common_bg_page.dart';
|
||||
import 'package:skywood/utils/models/drama/skywood_home.dart';
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
|
||||
const HomePage({super.key});
|
||||
|
||||
@override
|
||||
@@ -13,18 +17,107 @@ class HomePage extends StatefulWidget {
|
||||
|
||||
class _MainRootState extends State<HomePage> {
|
||||
|
||||
List<SkywoodHome> _homeData = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_getHomeData();
|
||||
}
|
||||
|
||||
void _getHomeData() {
|
||||
// home_v3_recommand
|
||||
// new_recommand
|
||||
// week_ranking
|
||||
// week_highest_recommend
|
||||
// marquee
|
||||
// home_banner
|
||||
// get_details_recommand
|
||||
PlayClient.getHomeData().then((value) {
|
||||
for (SkywoodHome element in value) {
|
||||
print('lele: ${element.moduleKey} : ${element.dataList.length}');
|
||||
}
|
||||
setState(() {
|
||||
_homeData = value;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CommonBgPage(
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
child: SafeArea(
|
||||
child: _homeData.isEmpty ? SizedBox() : CustomScrollView(
|
||||
slivers: [
|
||||
_buildTopTwoImgs(),
|
||||
_buildSpace(),
|
||||
DailyQuestWidget(
|
||||
dramaList: _homeData.firstWhere((element) => element.moduleKey == 'home_v3_recommand').dataList,
|
||||
),
|
||||
_buildSpace(height: 10),
|
||||
_buildTitleImg(ConstImg.homeTitleMystery),
|
||||
_buildSpace(),
|
||||
// 345 355
|
||||
_buildTitleImg(
|
||||
ConstImg.homeOpenNowBox,
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
||||
height: 355.h,
|
||||
),
|
||||
_buildSpace(height: 10),
|
||||
_buildTitleImg(ConstImg.homeTitleHot),
|
||||
_buildSpace(height: 300),
|
||||
_buildTitleImg(ConstImg.homeTitleWeekly),
|
||||
_buildSpace(height: 300),
|
||||
_buildTitleImg(ConstImg.homeTitleHotCate),
|
||||
_buildSpace(height: 300),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
SliverToBoxAdapter _buildTopTwoImgs() {
|
||||
// 104-76
|
||||
return SliverToBoxAdapter(
|
||||
child: Stack(
|
||||
children: [
|
||||
SizedBox(width: double.infinity, height: (204 + 104 - 28).h),
|
||||
Container(
|
||||
height: 204.h,
|
||||
padding: EdgeInsets.only(left: 25.w, top: 3.h, right: 25.w),
|
||||
child: HelpImg.asset(ConstImg.homeTopBg, fit: BoxFit.fill),
|
||||
),
|
||||
Positioned(
|
||||
top: (204 - 28).h,
|
||||
height: 104.h,
|
||||
width: AppScreen.screenWidth,
|
||||
child: HelpImg.asset(ConstImg.homeTitleDaily, fit: BoxFit.fill),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTitleImg() {
|
||||
return Container();
|
||||
SliverToBoxAdapter _buildSpace({double height = 20}) {
|
||||
return SliverToBoxAdapter(child: SizedBox(height: height.h));
|
||||
}
|
||||
}
|
||||
|
||||
SliverToBoxAdapter _buildTitleImg(
|
||||
String imgName, {
|
||||
double? height,
|
||||
double? width,
|
||||
EdgeInsets? padding,
|
||||
}) {
|
||||
// 104-76
|
||||
return SliverToBoxAdapter(
|
||||
child: Container(
|
||||
padding: padding ?? EdgeInsets.zero,
|
||||
width: width ?? double.infinity,
|
||||
height: height ?? 104.h,
|
||||
child: HelpImg.asset(imgName, fit: BoxFit.fill),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:skywood/global/const/common_color.dart';
|
||||
import 'package:skywood/utils/models/drama/skywood_drama.dart';
|
||||
import 'package:skywood/utils/tools/sky_time_tool.dart';
|
||||
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
|
||||
|
||||
import '../../../utils/tools/help_img.dart';
|
||||
|
||||
class DailyQuestWidget extends StatelessWidget {
|
||||
|
||||
const DailyQuestWidget({super.key,
|
||||
required this.dramaList,
|
||||
});
|
||||
|
||||
final List<SkywoodDrama> dramaList;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double height = 281.h;
|
||||
double width = 345.w;
|
||||
return SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
width: width,
|
||||
height: height,
|
||||
child: Stack(
|
||||
children: [
|
||||
HelpImg.asset(ConstImg.homeCardBg, height: height, width: width,fit: BoxFit.fill),
|
||||
Positioned(
|
||||
top: 20.h, bottom: 19.h, left: 22.5.w,
|
||||
width: 300.w,
|
||||
child: Column(
|
||||
children: [
|
||||
_buildFirstDrama(),
|
||||
_buildDramaList()
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDramaList() {
|
||||
if (dramaList.length < 2) return SizedBox.shrink();
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
spacing: 5.w,
|
||||
children: List.generate(dramaList.length-1, (index) {
|
||||
return HelpImg.network(dramaList[index+1].imageUrl, width: 95.w, height: 50.h, fit: BoxFit.cover);
|
||||
})
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFirstDrama() {
|
||||
if (dramaList.isEmpty) return SizedBox.shrink();
|
||||
SkywoodDrama drama = dramaList[0];
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: CommonColor.black, width: 1),
|
||||
),
|
||||
child: HelpImg.network(drama.imageUrl, width: 300.w, height: 160.h, fit: BoxFit.cover),
|
||||
),
|
||||
Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(child: SkyText(text: drama.name,
|
||||
fontSize: 14,
|
||||
fontFamily: 'Inter',
|
||||
fontWeight: FontWeight.w500,
|
||||
)),
|
||||
Row(
|
||||
children: [
|
||||
// Icon(Icons.heart_broken, size: 15, color: Colors.redAccent,),
|
||||
HelpImg.asset(ConstImg.heart, width: 18.w, height: 18.w),
|
||||
const SizedBox(width: 3),
|
||||
SkyText(text: SkyTimeTool.formatNum(drama.watchTotal),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:skywood/main/lib_file.dart';
|
||||
import 'package:skywood/pages/widgets/pixel_widgets.dart';
|
||||
|
||||
class LikePage extends StatefulWidget {
|
||||
|
||||
const LikePage({super.key});
|
||||
|
||||
@override
|
||||
@@ -11,11 +12,356 @@ class LikePage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MainRootState extends State<LikePage> {
|
||||
int _tabIndex = 0;
|
||||
|
||||
final List<String> _collectionTitles = const [
|
||||
'Undercover Play',
|
||||
"Don't Cross Me",
|
||||
'Two Worlds Apart',
|
||||
'Rekindled Scorn',
|
||||
'My Revenge is You',
|
||||
"Mr. Gu's Sweet Weakness",
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
||||
body: PixelPageBackground(
|
||||
child: SafeArea(
|
||||
bottom: false,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.fromLTRB(15.w, 44.h, 15.w, 0),
|
||||
child: PixelPanel(
|
||||
padding: EdgeInsets.fromLTRB(10.w, 18.h, 10.w, 22.h),
|
||||
child: Column(
|
||||
children: [
|
||||
_buildTabs(),
|
||||
SizedBox(height: 20.h),
|
||||
Expanded(
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 180),
|
||||
child: _tabIndex == 0
|
||||
? _buildCollection()
|
||||
: _buildPlayLog(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildTabs() {
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _LibraryTab(
|
||||
title: 'My Collection',
|
||||
selected: _tabIndex == 0,
|
||||
onTap: () => setState(() => _tabIndex = 0),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
Expanded(
|
||||
child: _LibraryTab(
|
||||
title: 'Play Log',
|
||||
selected: _tabIndex == 1,
|
||||
onTap: () => setState(() => _tabIndex = 1),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCollection() {
|
||||
return GridView.builder(
|
||||
key: const ValueKey('collection'),
|
||||
padding: EdgeInsets.only(top: 2.h, bottom: 120.h),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 3,
|
||||
mainAxisSpacing: 10.h,
|
||||
crossAxisSpacing: 7.w,
|
||||
childAspectRatio: 100 / 174,
|
||||
),
|
||||
itemCount: _collectionTitles.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _CollectionCard(title: _collectionTitles[index]);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPlayLog() {
|
||||
return ListView(
|
||||
key: const ValueKey('play-log'),
|
||||
padding: EdgeInsets.only(bottom: 120.h),
|
||||
children: [
|
||||
_ContinueCard(),
|
||||
SizedBox(height: 18.h),
|
||||
Text(
|
||||
'Watch History',
|
||||
style: TextStyle(
|
||||
color: const Color(0xFF1C1E1F),
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
_HistoryItem(title: 'As A Mafia Boss, I Refuse To Be An Extra'),
|
||||
SizedBox(height: 10.h),
|
||||
_HistoryItem(title: 'Fatal Vengeance'),
|
||||
SizedBox(height: 10.h),
|
||||
_HistoryItem(title: "Don't Cross Me"),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _LibraryTab extends StatelessWidget {
|
||||
const _LibraryTab({
|
||||
required this.title,
|
||||
required this.selected,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final bool selected;
|
||||
final VoidCallback onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
height: 45.h,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: selected ? const Color(0xFF16ED1E) : const Color(0xFFF6F6F6),
|
||||
border: Border.all(
|
||||
color: selected ? CommonColor.black : const Color(0xFFD6D6D6),
|
||||
width: 1.5.w,
|
||||
),
|
||||
boxShadow: selected
|
||||
? const [
|
||||
BoxShadow(color: Color(0xFF1C1E1F), offset: Offset(2, 2)),
|
||||
]
|
||||
: null,
|
||||
),
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: selected ? Colors.white : const Color(0xFFB2B2B2),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w900,
|
||||
height: 1,
|
||||
shadows: selected
|
||||
? const [Shadow(color: Color(0xFF1C1E1F), offset: Offset(1, 1))]
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _CollectionCard extends StatelessWidget {
|
||||
const _CollectionCard({required this.title});
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.fromLTRB(4.w, 8.h, 4.w, 6.h),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF4FFB6),
|
||||
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
|
||||
boxShadow: const [
|
||||
BoxShadow(color: Color(0xFF653CFA), offset: Offset(3, 3)),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: List.generate(4, (index) {
|
||||
return Container(
|
||||
width: 11.w,
|
||||
height: 6.h,
|
||||
margin: EdgeInsets.only(right: 5.w),
|
||||
decoration: BoxDecoration(
|
||||
color: index == 3
|
||||
? const Color(0xFFEAEAEA)
|
||||
: const Color(0xFF96FE9B),
|
||||
border: Border.all(
|
||||
color: const Color(0xFF1C1E1F),
|
||||
width: 0.8.w,
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
SizedBox(height: 8.h),
|
||||
const Expanded(child: PosterImage()),
|
||||
SizedBox(height: 8.h),
|
||||
Text(
|
||||
title,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: const Color(0xFF1C1E1F),
|
||||
fontSize: 13.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ContinueCard extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 140.h,
|
||||
padding: EdgeInsets.all(10.w),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEAE6FF),
|
||||
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const PosterImage(width: 90, height: 120, borderRadius: 2),
|
||||
SizedBox(width: 10.w),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Mogul And His Runaway Bride',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: const Color(0xFF1B1926),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
height: 1.25,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 18.h),
|
||||
Text(
|
||||
'Chapter 10 / 28',
|
||||
style: TextStyle(
|
||||
color: CommonColor.primacyColor,
|
||||
fontSize: 11.sp,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 6.h),
|
||||
_ProgressLine(value: 0.46),
|
||||
const Spacer(),
|
||||
const PixelButton(
|
||||
label: 'Continue Watch',
|
||||
width: 145,
|
||||
height: 29,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _HistoryItem extends StatelessWidget {
|
||||
const _HistoryItem({required this.title});
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 100.h,
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 6.h),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEAE6FF),
|
||||
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const PosterImage(width: 66, height: 88, borderRadius: 2),
|
||||
SizedBox(width: 10.w),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: CommonColor.black,
|
||||
fontSize: 13.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
height: 1.2,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'EP.40/85',
|
||||
style: TextStyle(
|
||||
color: CommonColor.primacyColor,
|
||||
fontSize: 11.sp,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
_ProgressLine(value: 0.46),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ProgressLine extends StatelessWidget {
|
||||
const _ProgressLine({required this.value});
|
||||
|
||||
final double value;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 6.h,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: 0.7),
|
||||
border: Border.all(color: const Color(0xFF1C1E1F), width: 0.5.w),
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FractionallySizedBox(
|
||||
widthFactor: value,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF00EE02),
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 4.w),
|
||||
Text('46%', style: TextStyle(fontSize: 10.sp, height: 1)),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:skywood/main/lib_file.dart';
|
||||
import 'package:skywood/pages/widgets/pixel_widgets.dart';
|
||||
|
||||
class MinePage extends StatefulWidget {
|
||||
|
||||
const MinePage({super.key});
|
||||
|
||||
@override
|
||||
@@ -11,11 +12,475 @@ class MinePage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MainRootState extends State<MinePage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
||||
body: PixelPageBackground(
|
||||
child: SafeArea(
|
||||
bottom: false,
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
SliverToBoxAdapter(child: SizedBox(height: 12.h)),
|
||||
SliverToBoxAdapter(child: _buildHeader()),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 18.h)),
|
||||
SliverToBoxAdapter(child: _buildPlayerCard()),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 10.h)),
|
||||
SliverToBoxAdapter(child: _buildWalletShop()),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 10.h)),
|
||||
SliverToBoxAdapter(child: _buildCheckpoint()),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 10.h)),
|
||||
SliverToBoxAdapter(child: _buildGameMenu()),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 120.h)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildHeader() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
_DecorIcon(icon: Icons.forest, color: const Color(0xFFFF5454)),
|
||||
SizedBox(width: 10.w),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 60.h,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF16ED1E),
|
||||
border: Border.all(color: CommonColor.black, width: 1.5.w),
|
||||
boxShadow: const [
|
||||
BoxShadow(color: Color(0xFF1C1E1F), offset: Offset(3, 3)),
|
||||
],
|
||||
),
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
style: TextStyle(
|
||||
fontSize: 24.sp,
|
||||
fontWeight: FontWeight.w900,
|
||||
height: 1,
|
||||
shadows: const [
|
||||
Shadow(
|
||||
color: Color(0xFF1C1E1F),
|
||||
offset: Offset(2, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
children: const [
|
||||
TextSpan(
|
||||
text: 'Profile ',
|
||||
style: TextStyle(color: Color(0xFFFFDC4C)),
|
||||
),
|
||||
TextSpan(
|
||||
text: 'Menu',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10.w),
|
||||
_DecorIcon(icon: Icons.live_tv, color: const Color(0xFF8965FB)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: List.generate(7, (index) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 3.w),
|
||||
child: Icon(
|
||||
index < 4 ? Icons.favorite : Icons.question_mark,
|
||||
size: index < 4 ? 18.w : 14.w,
|
||||
color: index.isEven
|
||||
? const Color(0xFF1AF23A)
|
||||
: const Color(0xFF653CFA),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPlayerCard() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
||||
child: PixelPanel(
|
||||
color: CommonColor.primacyColor,
|
||||
shadowColor: CommonColor.black,
|
||||
padding: EdgeInsets.zero,
|
||||
child: Column(
|
||||
children: [
|
||||
const PixelSectionLabel(label: 'Player Card'),
|
||||
Padding(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 68.w,
|
||||
height: 68.w,
|
||||
padding: EdgeInsets.all(4.w),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFE9C7FF),
|
||||
border: Border.all(color: CommonColor.black, width: 1.w),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.person_pin,
|
||||
size: 42.w,
|
||||
color: const Color(0xFF653CFA),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 15.w),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Vistor',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
Text(
|
||||
'ID: 32432233341',
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: 0.72),
|
||||
fontSize: 10.sp,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildWalletShop() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _SmallPanel(
|
||||
label: 'Treasure Wallet',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.inventory_2,
|
||||
size: 70.w,
|
||||
color: const Color(0xFFFFDC4C),
|
||||
),
|
||||
SizedBox(width: 6.w),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
_WalletValue(label: 'Coins', value: '15,890'),
|
||||
Divider(height: 8.h, color: Colors.white54),
|
||||
_WalletValue(label: 'Bonus', value: '20,000'),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10.w),
|
||||
Expanded(
|
||||
child: _SmallPanel(
|
||||
label: 'Item Shop',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.storefront,
|
||||
size: 66.w,
|
||||
color: const Color(0xFFFF8DB8),
|
||||
),
|
||||
SizedBox(width: 7.w),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Get More\nCoins',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
height: 1.1,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 14.h),
|
||||
const PixelButton(
|
||||
label: 'Store',
|
||||
width: 70,
|
||||
height: 20,
|
||||
color: Color(0xFFFF88CF),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCheckpoint() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
||||
child: PixelPanel(
|
||||
color: CommonColor.primacyColor,
|
||||
padding: EdgeInsets.zero,
|
||||
shadowColor: CommonColor.black,
|
||||
child: Column(
|
||||
children: [
|
||||
const PixelSectionLabel(label: 'Daily Checkpoint'),
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(16.w, 10.h, 10.w, 10.h),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: List.generate(7, (index) {
|
||||
return _DayBox(day: index + 1, active: index == 0);
|
||||
}),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
const PixelButton(
|
||||
label: 'Check In',
|
||||
width: 70,
|
||||
height: 22,
|
||||
color: Color(0xFFFF88CF),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildGameMenu() {
|
||||
final items = const [
|
||||
_MenuItem('Log In', Icons.login),
|
||||
_MenuItem('Wallet', Icons.account_balance_wallet),
|
||||
_MenuItem('Language', Icons.public),
|
||||
_MenuItem('Feedback', Icons.mail),
|
||||
_MenuItem('Settings', Icons.settings),
|
||||
_MenuItem('About Us', Icons.info),
|
||||
];
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
||||
child: PixelPanel(
|
||||
color: CommonColor.primacyColor,
|
||||
padding: EdgeInsets.zero,
|
||||
shadowColor: CommonColor.black,
|
||||
child: Column(
|
||||
children: [
|
||||
const PixelSectionLabel(label: 'Game Menu'),
|
||||
Padding(
|
||||
padding: EdgeInsets.all(10.w),
|
||||
child: GridView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 5,
|
||||
mainAxisSpacing: 8.h,
|
||||
crossAxisSpacing: 6.w,
|
||||
childAspectRatio: 1,
|
||||
),
|
||||
itemCount: items.length,
|
||||
itemBuilder: (context, index) => _MenuTile(item: items[index]),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SmallPanel extends StatelessWidget {
|
||||
const _SmallPanel({required this.label, required this.child});
|
||||
|
||||
final String label;
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PixelPanel(
|
||||
color: CommonColor.primacyColor,
|
||||
shadowColor: CommonColor.black,
|
||||
padding: EdgeInsets.zero,
|
||||
child: SizedBox(
|
||||
height: 134.h,
|
||||
child: Column(
|
||||
children: [
|
||||
PixelSectionLabel(label: label),
|
||||
Expanded(
|
||||
child: Padding(padding: EdgeInsets.all(8.w), child: child),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _WalletValue extends StatelessWidget {
|
||||
const _WalletValue({required this.label, required this.value});
|
||||
|
||||
final String label;
|
||||
final String value;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(color: Colors.white70, fontSize: 9.sp, height: 1),
|
||||
),
|
||||
SizedBox(height: 2.h),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 15.sp,
|
||||
fontWeight: FontWeight.w900,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DayBox extends StatelessWidget {
|
||||
const _DayBox({required this.day, required this.active});
|
||||
|
||||
final int day;
|
||||
final bool active;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: 28.w,
|
||||
height: 34.h,
|
||||
decoration: BoxDecoration(
|
||||
color: active ? const Color(0xFF91F473) : Colors.white,
|
||||
border: Border.all(color: CommonColor.black, width: 1.w),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text('Day', style: TextStyle(fontSize: 7.sp, height: 1)),
|
||||
SizedBox(height: 4.h),
|
||||
Text(
|
||||
'$day',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w800,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _MenuTile extends StatelessWidget {
|
||||
const _MenuTile({required this.item});
|
||||
|
||||
final _MenuItem item;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.fromLTRB(4.w, 4.h, 4.w, 6.h),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF8D62F7),
|
||||
border: Border.all(color: CommonColor.black, width: 1.w),
|
||||
boxShadow: const [
|
||||
BoxShadow(color: Color(0xFF1C1E1F), offset: Offset(2, 2)),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(item.icon, color: Colors.white, size: 25.w),
|
||||
SizedBox(height: 5.h),
|
||||
Text(
|
||||
item.label,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 8.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DecorIcon extends StatelessWidget {
|
||||
const _DecorIcon({required this.icon, required this.color});
|
||||
|
||||
final IconData icon;
|
||||
final Color color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border.all(color: CommonColor.black, width: 1.w),
|
||||
boxShadow: const [
|
||||
BoxShadow(color: Color(0xFF1C1E1F), offset: Offset(2, 2)),
|
||||
],
|
||||
),
|
||||
child: Icon(icon, color: color, size: 32.w),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _MenuItem {
|
||||
const _MenuItem(this.label, this.icon);
|
||||
|
||||
final String label;
|
||||
final IconData icon;
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:skywood/main/lib_file.dart';
|
||||
import 'package:skywood/pages/widgets/pixel_widgets.dart';
|
||||
|
||||
class SearchPage extends StatefulWidget {
|
||||
|
||||
const SearchPage({super.key});
|
||||
|
||||
@override
|
||||
@@ -11,11 +12,223 @@ class SearchPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MainRootState extends State<SearchPage> {
|
||||
final List<String> _titles = const [
|
||||
"Mr. Gu's Sweet Weakness",
|
||||
'Secret Wife with a Scar',
|
||||
'A Second Chance at Love',
|
||||
'Shadows of the Heart',
|
||||
'Boarding Pass To Love',
|
||||
'The Love Blueprint',
|
||||
'Who Dared Touch My Bride',
|
||||
'Famous Families Fled',
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
||||
backgroundColor: Colors.white,
|
||||
body: SafeArea(
|
||||
bottom: false,
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
SliverToBoxAdapter(child: _buildSearchBar()),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 16.h)),
|
||||
SliverToBoxAdapter(child: _buildHistory()),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 30.h)),
|
||||
SliverToBoxAdapter(child: _buildTitle('Trending Now')),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 10.h)),
|
||||
SliverToBoxAdapter(child: _buildTrendingList()),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 120.h)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildSearchBar() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(15.w, 10.h, 15.w, 0),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 34.w,
|
||||
height: 34.w,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFB6FFA7),
|
||||
border: Border.all(color: CommonColor.black, width: 1.w),
|
||||
boxShadow: const [
|
||||
BoxShadow(color: Color(0xFF91F473), offset: Offset(2, 2)),
|
||||
],
|
||||
),
|
||||
child: Icon(
|
||||
Icons.arrow_back_ios_new,
|
||||
size: 16.w,
|
||||
color: CommonColor.black,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10.w),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 36.h,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.w),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: CommonColor.black, width: 1.w),
|
||||
borderRadius: BorderRadius.circular(40.r),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.search, size: 16.w, color: CommonColor.black),
|
||||
SizedBox(width: 7.w),
|
||||
Text(
|
||||
'Search',
|
||||
style: TextStyle(
|
||||
color: const Color(0xFF3E3D40),
|
||||
fontSize: 12.sp,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHistory() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildTitle('Search History', fontSize: 14)),
|
||||
Icon(
|
||||
Icons.delete_outline,
|
||||
size: 18.w,
|
||||
color: const Color(0xFF888888),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0x0D000000),
|
||||
borderRadius: BorderRadius.circular(20.r),
|
||||
),
|
||||
child: Text(
|
||||
'Love',
|
||||
style: TextStyle(
|
||||
color: const Color(0x80000000),
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTitle(String title, {double fontSize = 18}) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: CommonColor.black,
|
||||
fontSize: fontSize.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1.1,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTrendingList() {
|
||||
return SizedBox(
|
||||
height: 446.h,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
||||
child: Wrap(
|
||||
direction: Axis.vertical,
|
||||
spacing: 10.h,
|
||||
runSpacing: 10.w,
|
||||
children: _titles
|
||||
.map((title) => _TrendingItem(title: title))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TrendingItem extends StatelessWidget {
|
||||
const _TrendingItem({required this.title});
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: 236.w,
|
||||
height: 104.h,
|
||||
child: Row(
|
||||
children: [
|
||||
const PosterImage(
|
||||
width: 80,
|
||||
height: 104,
|
||||
borderRadius: 4,
|
||||
showBorder: false,
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 10.h),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: CommonColor.black,
|
||||
fontSize: 13.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1.2,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.local_fire_department,
|
||||
size: 15.w,
|
||||
color: const Color(0xFFFF6A00),
|
||||
),
|
||||
SizedBox(width: 2.w),
|
||||
Text(
|
||||
'17.3K',
|
||||
style: TextStyle(
|
||||
color: const Color(0x80000000),
|
||||
fontSize: 10.sp,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:skywood/main/lib_file.dart';
|
||||
|
||||
import '../../global/client/user_client.dart';
|
||||
import '../../main/main_root.dart';
|
||||
import '../../utils/tools/help_nav.dart';
|
||||
import '../../utils/tools/token_manage.dart';
|
||||
|
||||
class SplashPage extends StatefulWidget {
|
||||
|
||||
const SplashPage({super.key});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _SplashPageState();
|
||||
}
|
||||
}
|
||||
|
||||
class _SplashPageState extends State<SplashPage> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_userRegister();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
bottom: false,
|
||||
child: HelpImg.asset(ConstImg.splashPage, fit: BoxFit.cover)),
|
||||
);
|
||||
}
|
||||
|
||||
void _userRegister() async {
|
||||
// 先拿token没有的话去注册
|
||||
final tm = TokenManager();
|
||||
String token = tm.get();
|
||||
print('tokkkkkk: $token');
|
||||
if (token.isNotEmpty) {
|
||||
// 成功后去到主页面
|
||||
print('object去主页面');
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
HelpNav.off(MainRoot());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
final res = await UserClient.register();
|
||||
if (res != null) {
|
||||
tm.save(res.token);
|
||||
HelpNav.off(MainRoot());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:skywood/main/lib_file.dart';
|
||||
|
||||
class PixelPageBackground extends StatelessWidget {
|
||||
const PixelPageBackground({super.key, required this.child});
|
||||
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
const Positioned.fill(child: ColoredBox(color: Colors.white)),
|
||||
const Positioned.fill(child: CustomPaint(painter: _GridPainter())),
|
||||
Positioned(
|
||||
left: -18.w,
|
||||
top: 178.h,
|
||||
child: Container(
|
||||
width: 52.w,
|
||||
height: 132.h,
|
||||
color: const Color(0xFF08F214),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: -20.w,
|
||||
top: 282.h,
|
||||
child: Container(
|
||||
width: 58.w,
|
||||
height: 286.h,
|
||||
color: const Color(0xFF08F214),
|
||||
),
|
||||
),
|
||||
child,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PixelPanel extends StatelessWidget {
|
||||
const PixelPanel({
|
||||
super.key,
|
||||
required this.child,
|
||||
this.padding,
|
||||
this.color = Colors.white,
|
||||
this.borderColor = const Color(0xFF1C1E1F),
|
||||
this.shadowColor = const Color(0xFF653CFA),
|
||||
});
|
||||
|
||||
final Widget child;
|
||||
final EdgeInsets? padding;
|
||||
final Color color;
|
||||
final Color borderColor;
|
||||
final Color shadowColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
border: Border.all(color: borderColor, width: 1.5.w),
|
||||
boxShadow: [
|
||||
BoxShadow(color: shadowColor, offset: Offset(4.w, 4.h)),
|
||||
BoxShadow(color: shadowColor, offset: Offset(-4.w, 4.h)),
|
||||
],
|
||||
),
|
||||
padding: padding ?? EdgeInsets.all(10.w),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PixelSectionLabel extends StatelessWidget {
|
||||
const PixelSectionLabel({
|
||||
super.key,
|
||||
required this.label,
|
||||
this.width,
|
||||
this.trailing,
|
||||
});
|
||||
|
||||
final String label;
|
||||
final double? width;
|
||||
final Widget? trailing;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 20.h,
|
||||
width: width?.w,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.w),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF7B54F6),
|
||||
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(width: 7.w, height: 7.w, color: const Color(0xFF34F04F)),
|
||||
SizedBox(width: 5.w),
|
||||
Expanded(
|
||||
child: Text(
|
||||
label,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
trailing ?? const SizedBox.shrink(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PixelButton extends StatelessWidget {
|
||||
const PixelButton({
|
||||
super.key,
|
||||
required this.label,
|
||||
this.onTap,
|
||||
this.width = 116,
|
||||
this.height = 28,
|
||||
this.color = const Color(0xFF8D62F7),
|
||||
});
|
||||
|
||||
final String label;
|
||||
final VoidCallback? onTap;
|
||||
final double width;
|
||||
final double height;
|
||||
final Color color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
width: width.w,
|
||||
height: height.h,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
|
||||
),
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w800,
|
||||
height: 1,
|
||||
shadows: const [
|
||||
Shadow(color: Color(0xFF1C1E1F), offset: Offset(1, 1)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PosterImage extends StatelessWidget {
|
||||
const PosterImage({
|
||||
super.key,
|
||||
this.width,
|
||||
this.height,
|
||||
this.borderRadius = 3,
|
||||
this.showBorder = true,
|
||||
});
|
||||
|
||||
final double? width;
|
||||
final double? height;
|
||||
final double borderRadius;
|
||||
final bool showBorder;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: width?.w,
|
||||
height: height?.h,
|
||||
decoration: BoxDecoration(
|
||||
border: showBorder
|
||||
? Border.all(color: const Color(0xFF1C1E1F), width: 0.8.w)
|
||||
: null,
|
||||
borderRadius: BorderRadius.circular(borderRadius.r),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: HelpImg.asset(ConstImg.homeCardBg, fit: BoxFit.cover),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _GridPainter extends CustomPainter {
|
||||
const _GridPainter();
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final gridPaint = Paint()
|
||||
..color = const Color(0xFFE0D8FF)
|
||||
..strokeWidth = 0.8;
|
||||
const step = 10.0;
|
||||
for (double x = 0; x <= size.width; x += step) {
|
||||
canvas.drawLine(Offset(x, 0), Offset(x, size.height), gridPaint);
|
||||
}
|
||||
for (double y = 0; y <= size.height; y += step) {
|
||||
canvas.drawLine(Offset(0, y), Offset(size.width, y), gridPaint);
|
||||
}
|
||||
|
||||
final blockPaint = Paint()..color = const Color(0xFFE0D8FF);
|
||||
canvas.drawRect(Rect.fromLTWH(80, 0, 34, 96), blockPaint);
|
||||
canvas.drawRect(Rect.fromLTWH(228, 0, 34, 32), blockPaint);
|
||||
canvas.drawRect(Rect.fromLTWH(278, 112, 34, 34), blockPaint);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
|
||||
}
|
||||
Reference in new issue
Block a user