欢迎光临
我们一直在努力

第11天:打造个人中心页面(小白也能学会)

文章目录

    • 🎯 先看效果
    • 📚 核心知识点拆解
      • 1. 基础架构:StatelessWidget
      • 2. 颜色管理:统一主题色
      • 3. 滚动优化:CustomScrollView + Sliver组件
      • 4. 视觉提升:渐变与阴影
        • 渐变背景
        • 头像阴影
      • 5. 组件封装:复用性提升
      • 6. 交互体验:InkWell水波纹
      • 7. 路由跳转:退出登录功能
    • 🚀 完整代码(可直接运行)
    • 📝 运行前准备
    • 总结

大家好!今天给大家带来一个超实用的Flutter实战教程——从零开始打造一个视觉效果拉满的绿色系个人中心页面。这个页面包含了渐变导航栏、卡片式菜单、水波纹交互等热门UI设计元素,代码简洁易懂,新手也能轻松上手!

🎯 先看效果

我们最终实现的个人中心包含这些核心特性:

  • 渐变背景的置顶导航栏(SliverAppBar)
  • 带阴影和边框的圆形头像
  • 数据统计卡片
  • 主题色统一的功能菜单
  • 交互友好的按钮和点击反馈
  • 响应式布局适配不同设备

在这里插入图片描述

📚 核心知识点拆解

1. 基础架构:StatelessWidget

class ProfilePage extends StatelessWidget {
const ProfilePage({Key? key}) : super(key: key);


Widget build(BuildContext context) {
// 页面内容
return Scaffold(...);
}
}

小白解读:

  • StatelessWidget 是无状态组件,适合内容不会动态变化的页面(比如个人中心)
  • build 方法是Flutter构建UI的核心,所有界面元素都在这里定义
  • Scaffold 是Flutter提供的基础页面骨架,包含导航栏、背景、主体内容等

2. 颜色管理:统一主题色

// 定义绿色系主色值,方便统一调整
const primaryGreen = Color(0xFF2E7D32); // 深绿主色
const lightGreen = Color(0xFF81C784); // 浅绿辅助色
const green50 = Color(0xFFE8F5E9); // 绿色背景浅色调

小白解读:

  • 把颜色值定义为常量,方便后期统一修改(改一处全页面生效)
  • Flutter中颜色用16进制表示,格式是0xFF + 6位颜色码(和前端的#RRGGBB对应)
  • 主色+辅助色+背景色的搭配原则,让页面视觉更统一

3. 滚动优化:CustomScrollView + Sliver组件

body: CustomScrollView(
slivers: [
// 顶部导航栏
SliverAppBar(...),
// 内容区域
SliverToBoxAdapter(...),
],
)

小白解读:

  • CustomScrollView 是Flutter的高级滚动组件,适合复杂的滚动场景
  • Sliver 可以理解为"可滚动的碎片",不同的Sliver组件组合实现复杂效果
  • SliverAppBar:支持展开/收起的导航栏,pinned: true 表示滚动时置顶
  • SliverToBoxAdapter:把普通Widget包装成Sliver,实现混合布局

4. 视觉提升:渐变与阴影

渐变背景

decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Colors.lightGreen.shade200, // 浅绿渐变起始
Colors.green.shade800, // 深绿渐变结束
],
),
),

头像阴影

boxShadow: [
BoxShadow(
color: primaryGreen.withOpacity(0.2),
blurRadius: 12, // 模糊半径
offset: const Offset(0, 6), // 偏移量
),
],

小白解读:

  • LinearGradient 实现线性渐变,可自定义起始/结束位置和颜色
  • BoxShadow 给组件添加阴影,让UI有层次感(不是扁平的)
  • withOpacity 调整颜色透明度,数值0-1之间

5. 组件封装:复用性提升

// 封装统计项组件
Widget _buildStatItem(String label, String value) {
return Column(...);
}

// 封装菜单卡片组件
Widget _buildMenuCard({
required String title,
required IconData icon,
required Color iconColor,
required List<Widget> items,
}) {
return Card(...);
}

小白解读:

  • 把重复的UI元素封装成独立方法,避免代码冗余
  • required 关键字表示参数是必填的
  • 封装后的组件可以通过传参实现不同样式,比如统一的主题色

6. 交互体验:InkWell水波纹

InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(8),
// 点击水波纹颜色适配绿色主题
splashColor: themeColor.withOpacity(0.1),
highlightColor: themeColor.withOpacity(0.05),
child: Padding(...),
)

小白解读:

  • InkWell 给任意Widget添加点击事件和水波纹效果
  • splashColor 是点击时的水波纹颜色
  • highlightColor 是长按/点击时的高亮颜色
  • 配合borderRadius让水波纹效果更美观

7. 路由跳转:退出登录功能

onPressed: () {
// 实现登出逻辑
Navigator.of(context).pushReplacementNamed('/login');
},

小白解读:

  • Navigator 是Flutter的路由管理工具
  • pushReplacementNamed 表示跳转到新页面并替换当前页面(退出登录后无法返回)
  • 需要提前在路由表中注册/login页面

🚀 完整代码(可直接运行)

import 'dart:ui';

import 'package:flutter/material.dart';

class ProfilePage extends StatelessWidget {
const ProfilePage({Key? key}) : super(key: key);


Widget build(BuildContext context) {
// 定义绿色系主色值,方便统一调整
const primaryGreen = Color(0xFF2E7D32); // 深绿主色
const lightGreen = Color(0xFF81C784); // 浅绿辅助色
const green50 = Color(0xFFE8F5E9); // 绿色背景浅色调

return Scaffold(
backgroundColor: green50,
body: CustomScrollView(
slivers: [
// 自定义顶部栏 – 绿色渐变
SliverAppBar(
expandedHeight: 280,
floating: false,
pinned: true,
backgroundColor: primaryGreen,
surfaceTintColor: primaryGreen,
flexibleSpace: FlexibleSpaceBar(
background: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Colors.lightGreen.shade200,
Colors.green.shade800,
],
),
),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
Row(
children: [
// 用户头像
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.white,
width: 3,
),
boxShadow: [
BoxShadow(
color: primaryGreen.withOpacity(0.2),
blurRadius: 12,
offset: const Offset(0, 6),
),
],
),
child: const CircleAvatar(
radius: 40,
backgroundImage: AssetImage(
'assets/images/flutter.jpg',
),
backgroundColor: lightGreen,
),
),
const SizedBox(width: 20),
// 用户信息
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
'用户昵称',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
letterSpacing: 0.5,
),
),
SizedBox(height: 8),
UserIdTag(),
],
),
),
],
),
const SizedBox(height: 30),
// 统计数据行
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildStatItem('订单', '12'),
_buildStatItem('收藏', '36'),
_buildStatItem('足迹', '48'),
_buildStatItem('优惠券', '5'),
],
),
],
),
),
),
),
),
),

// 内容区域
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
// 功能菜单卡片
_buildMenuCard(
title: '我的服务',
icon: Icons.grid_view,
iconColor: primaryGreen,
items: [
_buildMenuItem(Icons.payment, '我的订单', () {}, primaryGreen),
_buildMenuItem(Icons.favorite, '我的收藏', () {}, primaryGreen),
_buildMenuItem(Icons.history, '浏览记录', () {}, primaryGreen),
_buildMenuItem(Icons.card_giftcard, '优惠券', () {}, primaryGreen),
],
),
const SizedBox(height: 16),
// 设置菜单卡片
_buildMenuCard(
title: '系统设置',
icon: Icons.settings,
iconColor: primaryGreen,
items: [
_buildMenuItem(Icons.person, '个人信息', () {}, primaryGreen),
_buildMenuItem(Icons.notifications, '消息通知', () {}, primaryGreen),
_buildMenuItem(Icons.security, '账号安全', () {}, primaryGreen),
_buildMenuItem(Icons.help_outline, '帮助与反馈', () {}, primaryGreen),
_buildMenuItem(Icons.info_outline, '关于我们', () {}, primaryGreen),
],
),
const SizedBox(height: 24),
// 退出登录按钮
_buildLogoutButton(primaryGreen, context),
const SizedBox(height: 30),
],
),
),
),
],
),
);
}

// 统计项组件
Widget _buildStatItem(String label, String value) {
return Column(
children: [
Text(
value,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
shadows: [
Shadow(
color: Colors.black12,
offset: Offset(0, 1),
blurRadius: 2,
)
],
),
),
const SizedBox(height: 5),
Text(
label,
style: TextStyle(
fontSize: 14,
color: Colors.white.withOpacity(0.9),
fontWeight: FontWeight.w400,
),
),
],
);
}

// 菜单卡片组件
Widget _buildMenuCard({
required String title,
required IconData icon,
required Color iconColor,
required List<Widget> items,
}) {
return Card(
elevation: 3,
shadowColor: iconColor.withOpacity(0.15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(icon, color: iconColor, size: 20),
const SizedBox(width: 8),
Text(
title,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.grey[800],
letterSpacing: 0.3,
),
),
],
),
const SizedBox(height: 16),
...items,
],
),
),
);
}

// 菜单项组件
Widget _buildMenuItem(
IconData icon,
String title,
VoidCallback onTap,
Color themeColor,
) {
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(8),
splashColor: themeColor.withOpacity(0.1),
highlightColor: themeColor.withOpacity(0.05),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: themeColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Icon(
icon,
color: themeColor,
size: 20,
),
),
const SizedBox(width: 16),
Expanded(
child: Text(
title,
style: const TextStyle(
fontSize: 16,
color: Colors.black87,
fontWeight: FontWeight.w400,
),
),
),
Icon(
Icons.chevron_right,
color: Colors.grey[400],
size: 20,
),
],
),
),
);
}

// 退出登录按钮
Widget _buildLogoutButton(Color themeColor, BuildContext context) {
return SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton(
onPressed: () {
// 实现登出逻辑
Navigator.of(context).pushReplacementNamed('/login');
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
elevation: 2,
shadowColor: themeColor.withOpacity(0.1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
side: BorderSide(color: Colors.red.withOpacity(0.2), width: 1),
),
splashFactory: InkRipple.splashFactory,
),
child: const Text(
'退出登录',
style: TextStyle(
color: Colors.redAccent,
fontSize: 16,
fontWeight: FontWeight.w500,
letterSpacing: 0.5,
),
),
),
);
}
}

// 抽离用户ID标签组件
class UserIdTag extends StatelessWidget {
const UserIdTag({Key? key}) : super(key: key);


Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 0.2, sigmaY: 0.2),
child: const Text(
'用户ID: 123456',
style: TextStyle(
fontSize: 14,
color: Colors.white,
fontWeight: FontWeight.w400,
),
),
),
);
}
}

📝 运行前准备

  • 在pubspec.yaml中添加assets配置(如果使用本地图片):
  • flutter:
    assets:
    assets/images/

  • 确保有flutter.jpg图片文件在assets/images/目录下
  • 注册路由(在main.dart中):
  • MaterialApp(
    initialRoute: '/profile',
    routes: {
    '/profile': (context) => const ProfilePage(),
    '/login': (context) => const LoginPage(), // 替换为你的登录页
    },
    );

    总结

  • UI设计技巧:通过统一主题色、渐变、阴影和圆角,让页面视觉更美观,SliverAppBar实现了高级的折叠导航栏效果。
  • 代码优化:将重复UI封装成独立组件,提升代码复用性和可维护性,InkWell增强了交互体验。
  • 核心组件:CustomScrollView+Sliver系列组件是实现复杂滚动布局的关键,适合打造高颜值的移动端页面。
  • 赞(0)
    未经允许不得转载:171主机测评 » 第11天:打造个人中心页面(小白也能学会)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址