feat(mobile): redesign guide pages with fullscreen background images
向导页重新设计: 1. 页面1-4 改为全屏背景图片布局 - 移除 SafeArea,图片延伸到状态栏 - 移除文字标题和副标题(文字设计在图片中) - 仅保留底部页面指示器(白色圆点) 2. 页面5(欢迎加入页)也改为全屏背景图片 - 添加渐变遮罩(30%~60%黑色)提高可读性 - 表单区域改为透明背景 - 所有文字、输入框、单选按钮改为白色系 - 退出按钮文字从"退出 Exit"改为"退出" 3. 添加5张向导页背景图片 - guide_1.jpg ~ guide_4.jpg: 介绍页背景 - guide_5.png: 欢迎加入页背景 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
53320df220
commit
07448b381b
Binary file not shown.
|
After Width: | Height: | Size: 284 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 377 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 303 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 259 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
|
|
@ -38,28 +38,34 @@ class _GuidePageState extends ConsumerState<GuidePage> {
|
|||
final PageController _pageController = PageController();
|
||||
int _currentPage = 0;
|
||||
|
||||
// 向导页1-4的数据
|
||||
// 向导页1-5的数据 (第5页为欢迎加入页)
|
||||
// 支持 png、jpg、webp 等格式
|
||||
final List<GuidePageData> _guidePages = const [
|
||||
GuidePageData(
|
||||
imagePath: 'assets/images/guide_1.png',
|
||||
imagePath: 'assets/images/guide_1.jpg',
|
||||
title: '认种一棵榴莲树\n拥有真实RWA资产',
|
||||
subtitle: '绑定真实果园20年收益,让区块链与农业完美结合',
|
||||
),
|
||||
GuidePageData(
|
||||
imagePath: 'assets/images/guide_2.png',
|
||||
imagePath: 'assets/images/guide_2.jpg',
|
||||
title: '认种即可开启算力\n自动挖矿持续收益',
|
||||
subtitle: '每一棵树都对应真实资产注入,为算力提供真实价值支撑',
|
||||
),
|
||||
GuidePageData(
|
||||
imagePath: 'assets/images/guide_3.png',
|
||||
imagePath: 'assets/images/guide_3.jpg',
|
||||
title: '分享链接\n获得团队算力与收益',
|
||||
subtitle: '真实认种数据透明可信 · 团队越大算力越强',
|
||||
),
|
||||
GuidePageData(
|
||||
imagePath: 'assets/images/guide_4.png',
|
||||
imagePath: 'assets/images/guide_4.jpg',
|
||||
title: 'MPC多方安全\n所有地址与收益可审计',
|
||||
subtitle: '你的资产 · 安全透明 · 不可被篡改',
|
||||
),
|
||||
GuidePageData(
|
||||
imagePath: 'assets/images/guide_5.png',
|
||||
title: '欢迎加入',
|
||||
subtitle: '创建账号前的最后一步 · 请选择是否有推荐人',
|
||||
),
|
||||
];
|
||||
|
||||
@override
|
||||
|
|
@ -99,85 +105,53 @@ class _GuidePageState extends ConsumerState<GuidePage> {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: SafeArea(
|
||||
child: PageView.builder(
|
||||
controller: _pageController,
|
||||
onPageChanged: _onPageChanged,
|
||||
itemCount: 5, // 4个介绍页 + 1个欢迎加入页
|
||||
itemBuilder: (context, index) {
|
||||
if (index < 4) {
|
||||
return _buildGuidePage(_guidePages[index], index);
|
||||
} else {
|
||||
return _buildWelcomePage();
|
||||
}
|
||||
},
|
||||
),
|
||||
body: PageView.builder(
|
||||
controller: _pageController,
|
||||
onPageChanged: _onPageChanged,
|
||||
itemCount: 5, // 4个介绍页 + 1个欢迎加入页
|
||||
itemBuilder: (context, index) {
|
||||
if (index < 4) {
|
||||
return _buildGuidePage(_guidePages[index], index);
|
||||
} else {
|
||||
return _buildWelcomePage();
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建向导页 (页面1-4)
|
||||
/// 构建向导页 (页面1-4) - 全屏背景图片,无文字
|
||||
Widget _buildGuidePage(GuidePageData data, int index) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 64.h),
|
||||
// 图片区域
|
||||
Expanded(
|
||||
flex: 5,
|
||||
child: Container(
|
||||
width: 312.w,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
return Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
// 全屏背景图片
|
||||
if (data.imagePath != null)
|
||||
Image.asset(
|
||||
data.imagePath!,
|
||||
fit: BoxFit.cover,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
return Container(
|
||||
color: const Color(0xFFFFF8E7),
|
||||
),
|
||||
child: data.imagePath != null
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
child: Image.asset(
|
||||
data.imagePath!,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
return _buildPlaceholderImage(index);
|
||||
},
|
||||
),
|
||||
)
|
||||
: _buildPlaceholderImage(index),
|
||||
),
|
||||
child: _buildPlaceholderImage(index),
|
||||
);
|
||||
},
|
||||
)
|
||||
else
|
||||
Container(
|
||||
color: const Color(0xFFFFF8E7),
|
||||
child: _buildPlaceholderImage(index),
|
||||
),
|
||||
SizedBox(height: 48.h),
|
||||
// 标题
|
||||
Text(
|
||||
data.title,
|
||||
style: TextStyle(
|
||||
fontSize: 24.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1.33,
|
||||
color: const Color(0xFF292524),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
// 副标题
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
child: Text(
|
||||
data.subtitle,
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
height: 1.43,
|
||||
color: const Color(0xFF57534E),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 48.h),
|
||||
// 页面指示器
|
||||
_buildPageIndicator(),
|
||||
SizedBox(height: 80.h),
|
||||
],
|
||||
),
|
||||
// 底部页面指示器
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 80.h,
|
||||
child: _buildPageIndicator(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -223,10 +197,12 @@ class _GuidePageState extends ConsumerState<GuidePage> {
|
|||
return _WelcomePageContent(
|
||||
onNext: _goToOnboarding,
|
||||
onExit: _exitApp, // 退出整个应用
|
||||
backgroundImage: _guidePages[4].imagePath,
|
||||
pageIndicator: _buildPageIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建页面指示器
|
||||
/// 构建页面指示器 (所有页面都使用白色系,因为都有背景图)
|
||||
Widget _buildPageIndicator() {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
|
@ -239,8 +215,8 @@ class _GuidePageState extends ConsumerState<GuidePage> {
|
|||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: isActive
|
||||
? const Color(0xFF8E794A)
|
||||
: const Color(0xFFEAE0CD),
|
||||
? Colors.white
|
||||
: Colors.white.withValues(alpha: 0.4),
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
|
@ -252,10 +228,14 @@ class _GuidePageState extends ConsumerState<GuidePage> {
|
|||
class _WelcomePageContent extends ConsumerStatefulWidget {
|
||||
final VoidCallback onNext;
|
||||
final VoidCallback onExit;
|
||||
final String? backgroundImage;
|
||||
final Widget pageIndicator;
|
||||
|
||||
const _WelcomePageContent({
|
||||
required this.onNext,
|
||||
required this.onExit,
|
||||
this.backgroundImage,
|
||||
required this.pageIndicator,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -405,93 +385,152 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> {
|
|||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return SingleChildScrollView(
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: constraints.maxHeight,
|
||||
),
|
||||
child: IntrinsicHeight(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
child: Column(
|
||||
children: [
|
||||
// 退出按钮
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 32.h),
|
||||
child: GestureDetector(
|
||||
onTap: widget.onExit,
|
||||
child: Text(
|
||||
'退出 Exit',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
color: const Color(0xFFA99F93),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 80.h),
|
||||
// 欢迎标题
|
||||
Text(
|
||||
'欢迎加入',
|
||||
style: TextStyle(
|
||||
fontSize: 24.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1.33,
|
||||
color: const Color(0xFF6F6354),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
// 副标题
|
||||
Text(
|
||||
'创建账号前的最后一步 · 请选择是否有推荐人',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
height: 1.43,
|
||||
color: const Color(0xFFA99F93),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 48.h),
|
||||
// 选项区域
|
||||
_buildReferrerOptions(),
|
||||
const Spacer(),
|
||||
// 下一步按钮
|
||||
GestureDetector(
|
||||
onTap: _canProceed ? _saveReferralCodeAndProceed : null,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.symmetric(vertical: 16.h),
|
||||
child: Text(
|
||||
'下一步 (创建账号)',
|
||||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1.5,
|
||||
color: _canProceed
|
||||
? const Color(0xFFD4A84B) // 金色 - 可点击
|
||||
: const Color(0xFFCCC5B9), // 灰色 - 不可点击
|
||||
),
|
||||
textAlign: TextAlign.right,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 48.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
// 全屏背景图片
|
||||
if (widget.backgroundImage != null)
|
||||
Image.asset(
|
||||
widget.backgroundImage!,
|
||||
fit: BoxFit.cover,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
return Container(
|
||||
color: const Color(0xFFFFF8E7),
|
||||
);
|
||||
},
|
||||
)
|
||||
else
|
||||
Container(
|
||||
color: const Color(0xFFFFF8E7),
|
||||
),
|
||||
// 半透明遮罩,让内容更清晰
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Colors.black.withValues(alpha: 0.3),
|
||||
Colors.black.withValues(alpha: 0.6),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
// 内容区域
|
||||
SafeArea(
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return SingleChildScrollView(
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: constraints.maxHeight,
|
||||
),
|
||||
child: IntrinsicHeight(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
child: Column(
|
||||
children: [
|
||||
// 退出按钮
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 16.h),
|
||||
child: GestureDetector(
|
||||
onTap: widget.onExit,
|
||||
child: Text(
|
||||
'退出',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
color: Colors.white.withValues(alpha: 0.8),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 60.h),
|
||||
// 欢迎标题
|
||||
Text(
|
||||
'欢迎加入',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1.33,
|
||||
color: Colors.white,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: Colors.black.withValues(alpha: 0.5),
|
||||
blurRadius: 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
// 副标题
|
||||
Text(
|
||||
'创建账号前的最后一步 · 请选择是否有推荐人',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
height: 1.43,
|
||||
color: Colors.white.withValues(alpha: 0.9),
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: Colors.black.withValues(alpha: 0.5),
|
||||
blurRadius: 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 48.h),
|
||||
// 选项区域 (透明背景)
|
||||
_buildReferrerOptions(),
|
||||
const Spacer(),
|
||||
// 页面指示器
|
||||
widget.pageIndicator,
|
||||
SizedBox(height: 24.h),
|
||||
// 下一步按钮
|
||||
GestureDetector(
|
||||
onTap: _canProceed ? _saveReferralCodeAndProceed : null,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.symmetric(vertical: 16.h),
|
||||
decoration: BoxDecoration(
|
||||
color: _canProceed
|
||||
? const Color(0xFFD4A84B)
|
||||
: Colors.white.withValues(alpha: 0.3),
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Text(
|
||||
'下一步 (创建账号)',
|
||||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
height: 1.5,
|
||||
color: _canProceed
|
||||
? Colors.white
|
||||
: Colors.white.withValues(alpha: 0.6),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 32.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建推荐人选项
|
||||
/// 构建推荐人选项 (透明背景,白色文字)
|
||||
Widget _buildReferrerOptions() {
|
||||
return Column(
|
||||
children: [
|
||||
|
|
@ -511,7 +550,13 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> {
|
|||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
height: 1.5,
|
||||
color: const Color(0xFF6F6354),
|
||||
color: Colors.white,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: Colors.black.withValues(alpha: 0.5),
|
||||
blurRadius: 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -522,11 +567,11 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> {
|
|||
if (_hasReferrer)
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w),
|
||||
decoration: const BoxDecoration(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
width: 1,
|
||||
color: Color(0xFFEAE1D2),
|
||||
color: Colors.white.withValues(alpha: 0.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -539,7 +584,7 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> {
|
|||
hintText: '请输入推荐码 / 序列号',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
color: const Color(0xFFA99F93),
|
||||
color: Colors.white.withValues(alpha: 0.6),
|
||||
),
|
||||
border: InputBorder.none,
|
||||
isDense: true,
|
||||
|
|
@ -547,8 +592,9 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> {
|
|||
),
|
||||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
color: const Color(0xFF6F6354),
|
||||
color: Colors.white,
|
||||
),
|
||||
cursorColor: Colors.white,
|
||||
),
|
||||
),
|
||||
// 扫码按钮
|
||||
|
|
@ -559,7 +605,7 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> {
|
|||
child: Icon(
|
||||
Icons.camera_alt_outlined,
|
||||
size: 20.sp,
|
||||
color: const Color(0xFFA99F93),
|
||||
color: Colors.white.withValues(alpha: 0.8),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -583,7 +629,13 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> {
|
|||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
height: 1.5,
|
||||
color: const Color(0xFF6F6354),
|
||||
color: Colors.white,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: Colors.black.withValues(alpha: 0.5),
|
||||
blurRadius: 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -593,7 +645,7 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> {
|
|||
);
|
||||
}
|
||||
|
||||
/// 构建单选按钮
|
||||
/// 构建单选按钮 (白色系,适配深色背景)
|
||||
Widget _buildRadio(bool isSelected) {
|
||||
return Container(
|
||||
width: 20.w,
|
||||
|
|
@ -603,8 +655,8 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> {
|
|||
border: Border.all(
|
||||
width: isSelected ? 6.w : 2.w,
|
||||
color: isSelected
|
||||
? const Color(0xFF2563EB)
|
||||
: const Color(0xFFA99F93),
|
||||
? Colors.white
|
||||
: Colors.white.withValues(alpha: 0.5),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue