在这里插入图片描述

做移动开发这么多年,发现很多开发者对关于页面不太上心。觉得这玩意儿简单,随便写写就行了。

但实际上,关于我们页面是用户了解App的重要窗口,设计得好能给用户留下专业靠谱的印象。

今天就来聊聊怎么在Flutter for OpenHarmony上实现一个像样的关于页面。

页面要展示什么

先想清楚这个页面要放哪些内容。

用户点进关于页面,无非想知道这几件事:

  • 这App叫啥名,现在是什么版本

  • 这App是干嘛用的

  • 有哪些主要功能

  • 出了问题怎么联系开发者

所以我把页面分成四个区块来设计:

品牌区 放Logo、名称、版本号,让用户一眼认出这是啥App。

介绍区 用一段话说清楚App的定位和价值。

功能区 列出核心功能点,让用户快速了解能干啥。

联系区 提供邮箱、官网、电话等联系方式。

这样从上到下看下来,信息层次很清晰。

创建页面类

关于页面基本都是静态内容展示,不需要管理状态,用StatelessWidget就够了。

import 'package:flutter/material.dart';

先导入Material包,这是Flutter UI开发的基础。

没有这个包,后面的Widget都用不了。

class AboutPage extends StatelessWidget {
  const AboutPage({super.key});

类名叫AboutPage,简单直接。

用const构造函数是个好习惯,能让Flutter在编译期创建实例,运行时更省资源。

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('关于我们'),
      ),

build方法返回Scaffold,这是Material Design的标准页面结构。

AppBar设置页面标题为"关于我们",用户一看就知道这是什么页面。

      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            // 页面内容
          ],
        ),
      ),
    );
  }
}

body部分用SingleChildScrollView包裹,这样内容多了可以滚动。

padding设16像素让内容不贴边,看起来更舒服。

Column用来垂直排列各个区块。

Logo展示区实现

页面顶部是品牌展示区,Logo要放在最显眼的位置。

const SizedBox(height: 20),

先加20像素的顶部间距。

让Logo不要紧贴AppBar,留点呼吸空间。

Container(
  width: 100,
  height: 100,

Logo容器设置100x100的固定尺寸。

这个大小在手机屏幕上刚好,不会太大也不会太小。

  decoration: BoxDecoration(
    color: const Color(0xFF26A69A),
    borderRadius: BorderRadius.circular(20),
  ),

用BoxDecoration添加背景色和圆角。

颜色用的是App主题色,一种清新的青绿色。

圆角20像素让Logo看起来更柔和现代。

  child: const Icon(
    Icons.health_and_safety,
    size: 50,
    color: Colors.white,
  ),
),

容器里放一个健康相关的图标。

白色配青绿背景对比度刚好,很清晰。

实际项目中这里可以换成真实的Logo图片。

const SizedBox(height: 16),

Logo下面加16像素间距。

const Text(
  '口腔护理',
  style: TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.bold,
  ),
),

应用名称用24号粗体字,够醒目。

这是用户对App的第一印象,字体要够大够清晰。

const SizedBox(height: 8),

名称和版本号之间只留8像素。

因为它们关联紧密,不需要太大间距。

Text(
  '版本 1.0.0',
  style: TextStyle(
    color: Colors.grey.shade600,
  ),
),

版本号用灰色小字显示。

作为辅助信息不抢主角风头。

const SizedBox(height: 32),

品牌区和下面的介绍区之间留32像素大间距。

视觉上明确分隔两个区块。

应用介绍卡片

介绍区用卡片样式呈现,白色背景配圆角看起来很清爽。

Container(
  padding: const EdgeInsets.all(20),

容器设置20像素内边距。

让文字不贴着卡片边缘,阅读更舒适。

  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.circular(16),
  ),

白色背景配16像素圆角,简洁大方。

这种卡片样式在现代App中很常见。

  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [

内容用Column垂直排列。

crossAxisAlignment设为start让文字左对齐,符合阅读习惯。

      const Text(
        '应用介绍',
        style: TextStyle(
          fontWeight: FontWeight.bold,
          fontSize: 16,
        ),
      ),

卡片标题用16号粗体。

明确告诉用户这块内容是什么。

      const SizedBox(height: 12),

标题和正文之间留12像素间距。

      Text(
        '口腔护理是一款专注于口腔健康管理的应用...',
        style: TextStyle(
          color: Colors.grey.shade700,
          height: 1.6,
        ),
      ),
    ],
  ),
),

介绍文字用深灰色而不是纯黑,看起来更柔和。

height设1.6增加行间距,提升可读性。

const SizedBox(height: 16),

介绍卡片和功能卡片之间留16像素间距。

功能特点列表

功能区同样用卡片样式,里面是图标加文字的列表。

Container(
  padding: const EdgeInsets.all(20),
  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.circular(16),
  ),

卡片样式和介绍区保持一致。

视觉上统一协调,用户看着舒服。

  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      const Text(
        '功能特点',
        style: TextStyle(
          fontWeight: FontWeight.bold,
          fontSize: 16,
        ),
      ),
      const SizedBox(height: 12),

标题样式也和介绍区一样,保持风格统一。

      _buildFeatureItem(Icons.timer, '智能刷牙计时'),

第一个功能项是刷牙计时。

用timer图标很直观,一看就懂。

      _buildFeatureItem(Icons.edit_calendar, '全面护理记录'),

护理记录用日历图标。

表示记录每天的护理情况。

      _buildFeatureItem(Icons.favorite, '口腔健康评分'),

健康评分用爱心图标。

传达关爱健康的意思。

      _buildFeatureItem(Icons.menu_book, '丰富知识库'),

知识库用书本图标。

一看就知道是学习相关的功能。

      _buildFeatureItem(Icons.emoji_events, '成就激励系统'),

成就系统用奖杯图标。

激励用户坚持护理,增加趣味性。

    ],
  ),
),

五个功能项列完,卡片内容结束。

const SizedBox(height: 16),

功能卡片和联系卡片之间同样留16像素间距。

功能项组件封装

功能列表的每一项结构相同,抽成方法复用。

Widget _buildFeatureItem(
  IconData icon, 
  String text,
) {

方法接收图标和文字两个参数。

这样调用的时候只需要传这两个值就行。

  return Padding(
    padding: const EdgeInsets.only(bottom: 12),

外层Padding给每项底部加12像素间距。

让列表项之间不会太挤。

    child: Row(
      children: [
        Icon(
          icon,
          color: const Color(0xFF26A69A),
          size: 20,
        ),

Row水平排列图标和文字。

图标用主题色,大小20像素,和文字搭配协调。

        const SizedBox(width: 12),

图标和文字之间留12像素间距。

        Text(text),
      ],
    ),
  );
}

文字直接显示,用默认样式就行。

这样封装的好处是以后要加功能项,一行代码搞定。

要改样式也只用改这一个方法,所有地方都会生效。

联系方式区域

联系区是用户找我们的入口,信息要清晰完整。

Container(
  padding: const EdgeInsets.all(20),
  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.circular(16),
  ),

卡片样式继续保持统一。

三个卡片看起来是一个整体。

  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      const Text(
        '联系我们',
        style: TextStyle(
          fontWeight: FontWeight.bold,
          fontSize: 16,
        ),
      ),
      const SizedBox(height: 12),

标题和间距都和前面的卡片一样。

      _buildContactItem(
        Icons.email, 
        '邮箱', 
        'support@oralcare.com',
      ),

邮箱是最常用的联系方式,放在第一个。

用户有问题可以发邮件详细描述。

      _buildContactItem(
        Icons.language, 
        '官网', 
        'www.oralcare.com',
      ),

官网让用户可以了解更多信息。

比如产品介绍、使用教程等。

      _buildContactItem(
        Icons.phone, 
        '客服', 
        '400-123-4567',
      ),

电话方便用户直接沟通。

有些问题打电话说得更清楚。

    ],
  ),
),

三种联系方式基本够用了。

const SizedBox(height: 32),

联系卡片和版权信息之间留大间距。

联系项组件封装

联系方式项和功能项类似,但多了一个标签。

Widget _buildContactItem(
  IconData icon,
  String label,
  String value,
) {

方法接收三个参数:图标、标签、值。

比功能项多一个label参数。

  return Padding(
    padding: const EdgeInsets.only(bottom: 12),

同样用Padding加底部间距。

    child: Row(
      children: [
        Icon(
          icon,
          color: Colors.grey.shade600,
          size: 20,
        ),

和功能项不同的是,联系项图标用灰色。

视觉上和功能区区分开。

        const SizedBox(width: 12),

图标和文字间距12像素。

        Text(
          '$label:',
          style: TextStyle(
            color: Colors.grey.shade600,
          ),
        ),

标签用灰色显示,后面跟中文冒号。

        Text(value),
      ],
    ),
  );
}

值用默认黑色显示。

和标签形成对比,更容易阅读。

版权信息

页面最底部放版权声明。

Text(
  ' 2024 口腔护理 All Rights Reserved',
  style: TextStyle(
    color: Colors.grey.shade500,
    fontSize: 12,
  ),
),

版权信息用12号浅灰色字体。

低调但不缺席,这是App的法律声明。

虽然用户很少看,但必须要有。

const SizedBox(height: 16),

底部留点间距。

内容不要顶到屏幕最下面。

颜色搭配说明

整个页面的配色很简单:

主题色 0xFF26A69A 是一种青绿色。

用在Logo背景和功能图标上,传达健康清新的感觉。

白色 用于卡片背景,干净清爽。

灰色系 用于辅助文字。

不同深浅区分信息层级,深灰用于正文,浅灰用于次要信息。

这套配色和口腔护理App的定位很搭,给人专业可靠的感觉。

间距规范

页面中的间距也有规律:

8像素 用于紧密关联的元素。

比如应用名和版本号。

12像素 用于列表项之间。

以及标题和内容之间。

16像素 用于卡片之间的间距。

20像素 用于卡片内边距。

32像素 用于大区块之间的分隔。

保持间距一致,页面看起来更整齐专业。

代码组织建议

如果项目规模变大,可以考虑把一些通用组件抽出来:

卡片容器可以封装成InfoCard组件。

列表项可以封装成IconTextRow组件。

颜色值可以统一放到AppColors类里。

这样代码更好维护,其他页面也能复用这些组件。

后续优化方向

当前实现满足基本需求,但还可以继续优化:

点击交互 联系方式可以加点击事件。

点邮箱打开邮件App,点电话直接拨号。

用url_launcher插件就能实现。

深色模式 可以根据系统设置切换深色主题。

现在很多用户喜欢深色模式护眼。

动画效果 页面加载时给卡片加个淡入动画。

体验会更流畅。

多语言 如果App要国际化。

这个页面的文字都需要做本地化处理。

不过这些都是锦上添花,核心功能已经完成了。

小结

关于我们页面虽然简单,但细节处理好了能给用户留下专业的印象。

通过合理的模块划分、统一的视觉风格、可复用的组件封装,我们实现了一个结构清晰、易于维护的关于页面。

代码不多,但该有的都有了。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐