RN for OpenHarmony AnimeHub项目实战:关于页面开发

案例开源地址:https://atomgit.com/nutpi/Rn_openharmony_AnimeHub

关于页展示应用的基本信息,包括应用名称、版本号、功能介绍和技术栈。这篇来讲关于页的实现,重点是信息展示布局和品牌形象设计。

功能设计

关于页需要展示以下信息:

  • 应用标识 - Logo、名称、版本号
  • 功能介绍 - 应用是做什么的
  • 数据来源 - 数据从哪里来
  • 技术栈 - 使用了什么技术

关于页是应用的"名片",虽然用户不常访问,但它体现了应用的专业性和透明度。好的关于页应该简洁明了,让用户快速了解应用。

关于页还有法律合规的作用。展示数据来源和版权声明,可以避免潜在的法律问题。特别是使用第三方 API 时,明确说明数据来源是对原创者的尊重。
从用户心理角度看,关于页可以增加用户对应用的信任感。一个有完整关于页的应用,给人的感觉是"正规"、"专业"的,而不是"山寨"、"不靠谱"的。

组件导入

typescript 复制代码
import React from 'react';
import { View, ScrollView, StyleSheet, Text, Image, Linking } from 'react-native';
import { Colors, FontSize, Spacing, BorderRadius } from '../../theme';
import { Header, Icon } from '../../components/common';

导入说明:

  • ScrollView - 滚动容器,因为关于页内容可能超出一屏
  • Image - 图片组件,虽然当前用 Icon 代替,但保留了扩展性
  • Linking - 用于打开外部链接(虽然当前代码没用到,但保留了扩展性)
  • 其他是常规的组件和样式导入

Linking 是 React Native 提供的模块,可以打开 URL、拨打电话、发送邮件等。在关于页中,可能需要链接到官网、GitHub 仓库或反馈邮箱。虽然当前没用到,但导入了方便后续扩展。
导入但暂时不用的模块,在开发阶段是常见的。这表示开发者已经考虑到了这些功能,只是还没实现。当然,在正式发布前应该清理掉真正不需要的导入。

页面结构

typescript 复制代码
export const AboutScreen = ({ navigation }: any) => {
  return (
    <View style={styles.container}>
      <Header title="关于" showBack onBack={() => navigation.goBack()} />
      <ScrollView contentContainerStyle={styles.content}>

基础结构:

  • Header 显示标题和返回按钮
  • ScrollView 包裹内容
  • contentContainerStyle 设置内容容器样式

contentContainerStylestyle 的区别是 React Native 初学者常见的困惑点:

  • style 作用于 ScrollView 本身,控制 ScrollView 这个容器的样式
  • contentContainerStyle 作用于内部的内容容器,控制 ScrollView 里面内容的样式
    这里用 contentContainerStyle 设置内边距和居中对齐,是因为我们要控制的是内容的布局,而不是 ScrollView 本身。如果用 style 设置 padding,内容滚动时 padding 会固定不动,效果不对。
typescript 复制代码
<View style={styles.logoContainer}>
  <View style={styles.logo}>
    <Icon name="movie" size={48} color={Colors.primary} />
  </View>
  <Text style={styles.appName}>AnimeHub</Text>
  <Text style={styles.version}>版本 1.0.0</Text>
</View>

Logo 区域组成:

  • Logo 图标(用 Icon 组件代替图片)
  • 应用名称
  • 版本号

这里用 Icon 组件代替真实的 Logo 图片。在实际项目中,应该使用设计好的 Logo 图片。Icon 组件的好处是不需要额外的图片资源,适合原型开发和教程演示。
如果要用真实的 Logo 图片,代码会是这样:

typescript 复制代码
<Image 
  source={require('../../assets/logo.png')} 
  style={styles.logoImage} 
/>

版本号的格式 "1.0.0" 遵循语义化版本规范(Semantic Versioning):

  • 第一位(1)- 主版本号,有重大更新或不兼容的改动时增加
  • 第二位(0)- 次版本号,有新功能但向后兼容时增加
  • 第三位(0)- 修订号,有 bug 修复时增加
typescript 复制代码
logoContainer: {
  alignItems: 'center',
  marginBottom: Spacing.xxxl,
},
logo: {
  width: 100,
  height: 100,
  borderRadius: BorderRadius.xl,
  backgroundColor: Colors.primary + '20',
  alignItems: 'center',
  justifyContent: 'center',
  marginBottom: Spacing.md,
},

样式说明:

  • Logo 容器居中对齐,底部有较大间距
  • Logo 是 100x100 的圆角方形
  • 半透明主题色背景
  • 图标在容器内居中

Logo 的尺寸选择 100x100 是一个常见的大小,在手机屏幕上既醒目又不会太大。太小会显得不够重要,太大会占用太多空间。
borderRadius: BorderRadius.xl 让 Logo 有圆角。圆角的大小会影响视觉感受:小圆角显得硬朗,大圆角显得柔和。xl 级别的圆角让 Logo 看起来更友好。
Colors.primary + '20' 是在颜色值后面加透明度。假设 primary 是 '#6366F1',加上 '20' 后变成 '#6366F120',其中 20 是十六进制的透明度(约 12.5%)。这样背景是淡淡的主题色,不会太突兀。

typescript 复制代码
appName: {
  fontSize: FontSize.xxl,
  fontWeight: '700',
  color: Colors.text,
},
version: {
  fontSize: FontSize.sm,
  color: Colors.textSecondary,
  marginTop: Spacing.xs,
},

文字样式:

  • 应用名称用超大字号(xxl,可能是 24-28px),加粗(700)
  • 版本号用小字号(sm,可能是 12-14px),次要颜色(灰色)

应用名称是页面的视觉焦点,所以用最大的字号和最粗的字重。这是视觉层次的体现:重要的内容要突出,次要的内容要弱化。
版本号是辅助信息,用小字号和灰色,不抢夺注意力。用户通常不关心版本号,但在反馈问题时可能需要提供,所以还是要显示。
fontWeight: '700' 是加粗。在 CSS/React Native 中,字重从 100(最细)到 900(最粗),400 是正常,700 相当于 bold。

关于应用区块

typescript 复制代码
<View style={styles.section}>
  <Text style={styles.sectionTitle}>关于应用</Text>
  <Text style={styles.description}>
    AnimeHub 是一款动漫信息浏览应用,使用 Jikan API 获取 MyAnimeList 的数据。
    你可以浏览热门动漫、搜索感兴趣的作品、查看详细信息和评论。
  </Text>
</View>

内容说明:

  • 简要介绍应用的功能
  • 说明数据来源

应用介绍应该简洁明了,用一两句话说清楚应用是做什么的。用户不会在关于页花太多时间,所以信息要精炼。
这段介绍回答了三个问题:

  1. 这是什么应用?- 动漫信息浏览应用
  2. 数据从哪来?- Jikan API / MyAnimeList
  3. 能做什么?- 浏览、搜索、查看详情和评论
    好的应用介绍应该让用户在 5 秒内理解应用的价值。如果需要长篇大论才能解释清楚,说明应用定位不够清晰。

数据来源区块

typescript 复制代码
<View style={styles.section}>
  <Text style={styles.sectionTitle}>数据来源</Text>
  <Text style={styles.description}>
    本应用数据来自 Jikan API,这是一个非官方的 MyAnimeList API。
    所有动漫信息、图片和评论版权归原作者所有。
  </Text>
</View>

内容说明:

  • 说明数据来自 Jikan API
  • 声明版权归属

版权声明很重要。使用第三方 API 的数据时,应该明确说明数据来源和版权归属。这是对原创者的尊重,也是法律合规的要求。
"非官方的 MyAnimeList API" 这个说明很重要。Jikan API 是社区维护的,不是 MyAnimeList 官方提供的。明确这一点可以避免用户误解。
"版权归原作者所有" 是一个通用的免责声明。动漫的版权属于制作公司和原作者,我们只是展示信息,不拥有这些内容的版权。

技术栈区块

typescript 复制代码
<View style={styles.section}>
  <Text style={styles.sectionTitle}>技术栈</Text>
  <View style={styles.techList}>
    <View style={styles.techItem}>
      <Icon name="code" size={16} color={Colors.primary} />
      <Text style={styles.techText}>React Native</Text>
    </View>
    <View style={styles.techItem}>
      <Icon name="globe" size={16} color={Colors.primary} />
      <Text style={styles.techText}>Jikan API v4</Text>
    </View>
  </View>
</View>

技术栈展示:

  • React Native - 开发框架
  • Jikan API v4 - 数据接口

展示技术栈是开发者的习惯,也是对开源社区的致敬。用户可能不关心技术细节,但对于技术爱好者来说,这是有价值的信息。
每个技术项用图标 + 文字的形式展示:

  • code 图标代表代码/开发框架

  • globe 图标代表网络/API
    技术栈还可以添加更多项目,比如:

  • TypeScript - 编程语言

  • Zustand - 状态管理

  • React Navigation - 导航库

区块样式

typescript 复制代码
section: {
  width: '100%',
  marginBottom: Spacing.xl,
},
sectionTitle: {
  fontSize: FontSize.lg,
  fontWeight: '600',
  color: Colors.text,
  marginBottom: Spacing.sm,
},
description: {
  fontSize: FontSize.md,
  color: Colors.textSecondary,
  lineHeight: 22,
},

样式说明:

  • 区块宽度 100%,占满容器
  • 区块之间有间距(xl)
  • 标题用大字号(lg),加粗(600)
  • 描述文字用中等字号(md),次要颜色
  • lineHeight: 22 增加行高,提高可读性

width: '100%' 是必要的,因为父容器设置了 alignItems: 'center',子元素默认会收缩到内容宽度。设置 100% 让区块占满宽度。
行高(lineHeight)对于多行文本很重要。默认的行高可能太紧凑,文字挤在一起不好阅读。22px 的行高配合 14-16px 的字号,行距大约是 1.4-1.6 倍,是比较舒适的阅读体验。
fontWeight: '600' 是半粗体,比正常(400)粗,比粗体(700)细。用于标题可以突出但不会太重。

技术栈样式

typescript 复制代码
techList: {
  flexDirection: 'row',
  flexWrap: 'wrap',
  gap: Spacing.md,
},
techItem: {
  flexDirection: 'row',
  alignItems: 'center',
  gap: Spacing.sm,
  paddingHorizontal: Spacing.md,
  paddingVertical: Spacing.sm,
  backgroundColor: Colors.backgroundCard,
  borderRadius: BorderRadius.md,
},
techText: {
  fontSize: FontSize.sm,
  color: Colors.text,
},

样式说明:

  • 技术栈列表横向排列,自动换行
  • 每个技术项是一个小卡片
  • 卡片内有图标和文字,横向排列
  • 使用 gap 设置间距

flexWrap: 'wrap' 让子元素在一行放不下时自动换行。这样即使技术栈很多,也能正常显示,不会超出屏幕。
gap 是 Flexbox 的属性,用于设置子元素之间的间距。比用 margin 更方便,因为不需要处理第一个和最后一个元素的边距问题。
技术项设计成小卡片的形式,有背景色和圆角,看起来像"标签"。这种设计在现代应用中很常见,比纯文字列表更有视觉吸引力。

内容容器样式

typescript 复制代码
content: {
  padding: Spacing.xl,
  alignItems: 'center',
},

样式说明:

  • 四周有较大内边距(xl,可能是 24-32px)
  • 内容居中对齐

alignItems: 'center' 让所有子元素水平居中。这是关于页的常见布局,Logo 和文字都居中显示,看起来更正式、更有仪式感。
较大的内边距让内容不贴边,有"呼吸感"。关于页不需要塞很多内容,留白反而让页面更优雅。

可扩展的功能

关于页可以添加更多功能:

typescript 复制代码
// 打开官网
const openWebsite = () => {
  Linking.openURL('https://example.com');
};

// 发送反馈邮件
const sendFeedback = () => {
  Linking.openURL('mailto:feedback@example.com?subject=AnimeHub反馈');
};

// 打开 GitHub 仓库
const openGitHub = () => {
  Linking.openURL('https://github.com/example/animehub');
};

// 查看开源协议
const openLicense = () => {
  navigation.navigate('License');
};

可添加的功能:

  • 官网链接 - 让用户了解更多
  • 反馈邮箱 - 收集用户反馈
  • GitHub 仓库 - 开源项目必备
  • 开源协议 - 说明代码的使用许可
  • 隐私政策 - 应用商店上架要求
  • 用户协议 - 应用商店上架要求
  • 更新日志 - 让用户了解版本变化

这些功能在实际项目中可能是必需的。特别是隐私政策和用户协议,在应用商店上架时通常是必须提供的。苹果和谷歌都要求应用提供隐私政策链接。

Linking 的使用详解

typescript 复制代码
// 打开网页
Linking.openURL('https://example.com');

// 打开邮件,可以预填主题和内容
Linking.openURL('mailto:email@example.com?subject=主题&body=内容');

// 拨打电话
Linking.openURL('tel:+8612345678901');

// 发送短信
Linking.openURL('sms:+8612345678901');

// 打开地图(iOS)
Linking.openURL('maps://app?daddr=北京市');

// 打开应用商店
Linking.openURL('market://details?id=com.example.app'); // Android
Linking.openURL('itms-apps://itunes.apple.com/app/id123456789'); // iOS

Linking 支持的协议:

  • https:// - 打开网页,会调用系统浏览器
  • mailto: - 打开邮件应用,可以预填收件人、主题、内容
  • tel: - 打开电话应用,准备拨打指定号码
  • sms: - 打开短信应用
  • market:// - 打开 Android 应用商店
  • itms-apps:// - 打开 iOS App Store

Linking 是跨平台的,但某些协议只在特定平台有效。使用前最好用 Linking.canOpenURL() 检查是否支持:

typescript 复制代码
const supported = await Linking.canOpenURL(url);
if (supported) {
  await Linking.openURL(url);
} else {
  Alert.alert('无法打开链接');
}

在鸿蒙系统上,Linking 的行为可能有所不同,需要实际测试。但基本的 https 链接应该是支持的。

版本号的管理

当前版本号是硬编码的:

typescript 复制代码
<Text style={styles.version}>版本 1.0.0</Text>

更好的做法是从配置文件读取:

typescript 复制代码
// 方案一:从 package.json 读取
import { version } from '../../package.json';

<Text style={styles.version}>版本 {version}</Text>
typescript 复制代码
// 方案二:使用 react-native-device-info 库
import DeviceInfo from 'react-native-device-info';

const version = DeviceInfo.getVersion(); // 如 "1.0.0"
const buildNumber = DeviceInfo.getBuildNumber(); // 如 "1"

<Text style={styles.version}>版本 {version} ({buildNumber})</Text>

从 package.json 读取版本号可以保证关于页显示的版本和实际版本一致。每次发版只需要修改 package.json,不需要手动更新关于页。
react-native-device-info 是一个常用的库,可以获取设备和应用的各种信息,包括版本号、设备型号、系统版本等。如果需要更多设备信息,推荐使用这个库。
显示 build number 对于测试和问题排查很有帮助。同一个版本号可能有多个 build,通过 build number 可以精确定位。

设计原则

关于页的设计原则:

  • 简洁 - 信息精炼,不要堆砌,用户不会在这里花太多时间
  • 专业 - 体现应用的品质,Logo、排版、文案都要讲究
  • 透明 - 说明数据来源和版权,建立用户信任
  • 可访问 - 提供联系方式,让用户能够反馈问题

关于页虽然不是核心功能,但它是应用的"门面"之一。一个精心设计的关于页可以提升用户对应用的信任感。
很多开发者忽视关于页,随便写几行文字就完事。但用户在决定是否信任一个应用时,可能会看关于页。一个完善的关于页说明开发者是认真的。

与设置页的关系

关于页通常从设置页进入:

typescript 复制代码
// 设置页中
<SettingItem
  icon="info"
  title="关于"
  onPress={() => navigation.navigate('About')}
  showArrow
/>

导航路径:

个人中心 → 设置 → 关于

这是常见的导航结构。关于页是设置页的子页面,用户需要两次点击才能到达。这符合用户的心理预期,因为关于页不是常用功能。
也有应用把关于页放在更显眼的位置,比如个人中心的底部。这取决于应用的定位和设计风格。

关于页的法律意义

关于页不仅是展示信息,还有法律意义:

  • 版权声明 - 说明内容的版权归属,避免侵权纠纷
  • 隐私政策 - 说明如何收集和使用用户数据,是 GDPR 等法规的要求
  • 用户协议 - 规定用户使用应用的条款,保护开发者权益
  • 开源协议 - 如果使用了开源代码,需要遵守相应的协议

在中国,应用上架各大应用商店都需要提供隐私政策。在欧洲,GDPR 要求更严格。在美国,CCPA 也有类似要求。关于页是放置这些法律文件链接的合适位置。

小结

关于页是应用的信息展示页面,包含 Logo、应用名称、版本号、功能介绍、数据来源和技术栈。页面布局居中对齐,信息分区块展示,整体风格简洁专业。

Logo 区域是页面的视觉焦点,用大尺寸图标和粗体文字突出显示。描述文字用次要颜色和适当的行高,提高可读性。技术栈用小卡片的形式展示,横向排列,自动换行。

关于页还可以扩展更多功能,如官网链接、反馈邮箱、开源协议等。Linking 模块可以打开外部链接、邮件、电话等,是实现这些功能的关键。

版本号建议从配置文件读取,而不是硬编码,这样可以保证显示的版本和实际版本一致。关于页虽然不是核心功能,但体现了应用的专业性和开发者的态度。

下一篇会讲放送时间表页面,展示每周的动漫播出时间。


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

相关推荐
松涛和鸣2 小时前
DAY55 Getting Started with ARM and IMX6ULL
linux·服务器·网络·arm开发·数据库·html
huahualaly3 小时前
重建oracle测试库步骤
数据库·oracle·ffmpeg
墨香幽梦客3 小时前
数据库选型对比:MySQL、Oracle与PostgreSQL的企业应用场景分析
数据库·mysql·oracle
wei_shuo3 小时前
多模一体破局:金仓数据库引领文档数据库国产化新征程
数据库·金仓数据库
Coder_Boy_3 小时前
基于SpringAI的在线考试系统-数据库 表结构 & 完整外键依赖关系梳理
java·数据库·人工智能·软件工程
摘星编程3 小时前
React Native for OpenHarmony 实战:I18n 国际化详解
javascript·react native·react.js
摘星编程4 小时前
React Native for OpenHarmony 实战:Localization 本地化详解
javascript·react native·react.js
清风拂山岗 明月照大江4 小时前
MySQL进阶
数据库·sql·mysql
努力进修4 小时前
金仓数据库:多模融合内核驱动,重构国产化文档数据库新生态
数据库·重构