ReactNative for Harmony项目鸿蒙化三方库集成实战:react-native-elements
库名称: @rneui/themed 和 @rneui/base当前版本官方仓库主要功能提供完整的 UI 组件库(Button、Card、List、Avatar、Input 等)支持主题定制跨平台一致的设计风格完全兼容 Android、iOS 和 HarmonyOS通过集成,我们为项目添加了一套完整的 UI 组件库。这个库提供了丰富的组件、统一的主题系统和跨平台的一致性,可以大大提升开发效率和用户
RN项目鸿蒙化三方库集成实战:react-native-elements
📋 前言
React Native Elements 是一个跨平台的 React Native UI 组件库,提供了一套完整且美观的 UI 组件。它遵循 React Native 的设计原则,支持主题定制,并且兼容 Android、iOS 和 HarmonyOS 三端。使用 React Native Elements 可以大大提升开发效率,构建出美观一致的用户界面。
🎯 库简介
基本信息
- 库名称: @rneui/themed 和 @rneui/base
- 当前版本: 4.0.0-rc.8 (@rneui/themed) / 4.0.0-rc.7 (@rneui/base)
- 官方仓库: https://github.com/react-native-elements/react-native-elements
- 主要功能:
- 提供完整的 UI 组件库(Button、Card、List、Avatar、Input 等)
- 支持主题定制
- 跨平台一致的设计风格
- 完全兼容 Android、iOS 和 HarmonyOS
为什么需要这个库?
- 提高开发效率: 提供开箱即用的精美组件
- 设计一致性: 统一的视觉风格和交互体验
- 主题定制: 支持全局主题和组件级主题
- 跨平台兼容: 在三端提供一致的体验
- 社区支持: 活跃的社区和完善的文档
📦 安装步骤
1. 使用 npm 安装
在项目根目录执行以下命令:
npm install @rneui/themed@4.0.0-rc.8
npm install @rneui/base@4.0.0-rc.7
2. 验证安装
安装完成后,检查 package.json 文件,应该能看到新增的依赖:
{
"dependencies": {
"@rneui/themed": "4.0.0-rc.8",
"@rneui/base": "4.0.0-rc.7",
// ... 其他依赖
}
}
🔧 HarmonyOS 平台配置
1. 依赖库配置
react-native-elements HarmonyOS 侧实现依赖以下库的原生端代码:
- @react-native-oh-tpl/react-native-safe-area-context
- @react-native-oh-tpl/react-native-linear-gradient
如已在 HarmonyOS 工程中引入过这些库,则无需再次引入。如未引入,请参考对应文档的 Link 章节进行引入。
不懂得参考我的另一篇文章:适配react-native-picker
还有:官方适配说明
2. 配置字体文件(可选)
如果需要使用 react-native-elements 的图标功能,需要配置字体文件。
步骤 1: 获取字体文件
从 react-native-vector-icons 的 GitHub 仓库下载字体文件:
https://github.com/oblador/react-native-vector-icons/tree/master/Fonts
下载所需的字体文件(如 FontAwesome.ttf、MaterialIcons.ttf 等)。
步骤 2: 复制字体文件
将下载的字体文件复制到 entry/src/main/resources/rawfile/fonts 目录下。
步骤 3: 配置字体注册
打开 entry/src/main/ets/pages/Index.ets,在 RNApp 配置中添加字体映射(根据实际下载的字体文件):
RNApp({
rnInstanceConfig: {
fontResourceByFontFamily: {
// 根据实际下载的字体文件配置,例如:
// 'FontAwesome': $rawfile('fonts/FontAwesome.ttf'),
// 'MaterialIcons': $rawfile('fonts/MaterialIcons.ttf'),
}
}
})
注意:如果项目中已经配置过 react-native-vector-icons 的字体,可以跳过此步骤。
3. 配置 CMakeLists
如果未引入 react-native-safe-area-context 或 react-native-linear-gradient,需要配置:
修改 entry/src/main/cpp/CMakeLists.txt:
# 添加 react-native-safe-area-context
add_subdirectory("${OH_MODULES}/@react-native-oh-tpl/react-native-safe-area-context/src/main/cpp" ./safe-area)
target_link_libraries(rnoh_app PUBLIC rnoh_safe_area)
# 添加 react-native-linear-gradient
add_subdirectory("${OH_MODULES}/@react-native-oh-tpl/react-native-linear-gradient/src/main/cpp" ./linear-gradient)
target_link_libraries(rnoh_app PUBLIC rnoh_linear_gradient)
4. 配置 PackageProvider
修改 entry/src/main/cpp/PackageProvider.cpp:
#include "SafeAreaContextPackage.h"
#include "LinearGradientPackage.h"
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
std::make_shared<RNOHGeneratedPackage>(ctx),
std::make_shared<SafeAreaContextPackage>(ctx),
std::make_shared<LinearGradientPackage>(ctx),
};
}
5. 配置 RNPackagesFactory
修改 entry/src/main/ets/RNPackagesFactory.ts:
import { SafeAreaViewPackage } from '@react-native-oh-tpl/react-native-safe-area-context/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
new SafeAreaViewPackage(ctx),
];
💻 完整代码示例
下面是一个完整的示例,展示了 react-native-elements 的各种常用组件:
import React, { useState } from 'react';
import {
SafeAreaView,
ScrollView,
StyleSheet,
View,
Alert,
} from 'react-native';
import {
Avatar,
Button,
Card,
Icon,
Input,
ListItem,
SearchBar,
Slider,
Text,
CheckBox,
ThemeProvider,
createTheme,
} from '@rneui/themed';
// 创建自定义主题
const theme = createTheme({
lightColors: {
primary: '#2089dc',
secondary: '#3ac4fa',
grey0: '#f7f7f7',
grey1: '#ededed',
grey2: '#dadada',
grey3: '#b7b7b7',
grey4: '#6e6e6e',
grey5: '#3b3b3b',
},
darkColors: {
primary: '#2089dc',
secondary: '#3ac4fa',
grey0: '#2c2c2c',
grey1: '#383838',
grey2: '#464646',
grey3: '#666666',
grey4: '#999999',
grey5: '#d9d9d9',
},
mode: 'light',
});
function ElementsDemo() {
const [value, setValue] = useState('');
const [sliderValue, setSliderValue] = useState(0.5);
const [checked, setChecked] = useState(false);
const [selectedIndex, setSelectedIndex] = useState(0);
return (
<ThemeProvider theme={theme}>
<SafeAreaView style={styles.container}>
<ScrollView>
{/* 1. Button 按钮 */}
<Card containerStyle={styles.card}>
<Card.Title>Button 按钮</Card.Title>
<Card.Divider />
<View style={styles.buttonContainer}>
<Button title="Primary" />
<Button title="Secondary" type="outline" />
<Button title="Clear" type="clear" />
</View>
<View style={styles.buttonContainer}>
<Button
title="With Icon"
icon={<Icon name="home" color="#ffffff" />}
iconRight
/>
<Button
title="Loading"
loading
/>
</View>
</Card>
{/* 2. Avatar 头像 */}
<Card containerStyle={styles.card}>
<Card.Title>Avatar 头像</Card.Title>
<Card.Divider />
<View style={styles.avatarContainer}>
<Avatar
size="large"
rounded
source={{ uri: 'https://randomuser.me/api/portraits/men/36.jpg' }}
/>
<Avatar
size="large"
rounded
title="JD"
containerStyle={{ backgroundColor: '#2089dc' }}
/>
<Avatar
size="large"
rounded
icon={{ name: 'user', type: 'font-awesome' }}
containerStyle={{ backgroundColor: '#2089dc' }}
/>
</View>
</Card>
{/* 3. Input 输入框 */}
<Card containerStyle={styles.card}>
<Card.Title>Input 输入框</Card.Title>
<Card.Divider />
<Input
placeholder="Basic input"
onChangeText={(text) => setValue(text)}
/>
<Input
placeholder="With icon"
leftIcon={{ type: 'font-awesome', name: 'user' }}
/>
<Input
placeholder="Error"
errorStyle={{ color: 'red' }}
errorMessage="ENTER A VALID ERROR HERE"
/>
</Card>
{/* 4. SearchBar 搜索栏 */}
<Card containerStyle={styles.card}>
<Card.Title>SearchBar 搜索栏</Card.Title>
<Card.Divider />
<SearchBar
placeholder="Type Here..."
onChangeText={(text) => setValue(text)}
value={value}
round
/>
</Card>
{/* 5. Slider 滑块 */}
<Card containerStyle={styles.card}>
<Card.Title>Slider 滑块</Card.Title>
<Card.Divider />
<Slider
value={sliderValue}
onValueChange={setSliderValue}
maximumValue={1}
minimumValue={0}
step={0.1}
allowTouchTrack
trackStyle={{ height: 5, backgroundColor: 'transparent' }}
thumbStyle={{ height: 20, width: 20, backgroundColor: 'transparent' }}
thumbProps={{
children: (
<Icon
name="circle"
type="font-awesome"
size={20}
reverse
color="#2089dc"
/>
),
}}
/>
<Text>Value: {sliderValue.toFixed(1)}</Text>
</Card>
{/* 6. CheckBox 复选框 */}
<Card containerStyle={styles.card}>
<Card.Title>CheckBox 复选框</Card.Title>
<Card.Divider />
<CheckBox
title="Click Here"
checked={checked}
onPress={() => setChecked(!checked)}
/>
<CheckBox
center
title="Click Here"
checked={checked}
onPress={() => setChecked(!checked)}
/>
<CheckBox
center
title="Click Here"
checkedIcon={<Icon name="checkbox" type="font-awesome" size={25} color="#2089dc" />}
uncheckedIcon={<Icon name="square-o" type="font-awesome" size={25} color="#2089dc" />}
checked={checked}
onPress={() => setChecked(!checked)}
/>
</Card>
{/* 7. ListItem 列表项 */}
<Card containerStyle={styles.card}>
<Card.Title>ListItem 列表项</Card.Title>
<Card.Divider />
<View>
{[
'Appointments',
'Trips',
'Favorites',
'Settings',
].map((l, i) => (
<ListItem key={i} bottomDivider>
<Icon name={l} />
<ListItem.Content>
<ListItem.Title>{l}</ListItem.Title>
</ListItem.Content>
<ListItem.Chevron />
</ListItem>
))}
</View>
</Card>
{/* 8. Icon 图标 */}
<Card containerStyle={styles.card}>
<Card.Title>Icon 图标</Card.Title>
<Card.Divider />
<View style={styles.iconContainer}>
<Icon name="home" type="font-awesome" size={30} />
<Icon name="heart" type="font-awesome" size={30} color="#e74c3c" />
<Icon name="star" type="font-awesome" size={30} color="#f1c40f" />
<Icon name="check-circle" type="font-awesome" size={30} color="#2ecc71" />
</View>
</Card>
</ScrollView>
</SafeAreaView>
</ThemeProvider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f7f7f7',
},
card: {
marginBottom: 15,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
marginBottom: 15,
},
avatarContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
paddingVertical: 15,
},
iconContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
paddingVertical: 15,
},
});
export default ElementsDemo;

💻 代码讲解
1. Button 按钮组件
<Button title="Primary" />
<Button title="Secondary" type="outline" />
<Button title="Clear" type="clear" />
Button 组件支持多种类型:
solid(默认): 实心按钮outline: 轮廓按钮clear: 透明按钮
可以添加图标、加载状态等。
2. Avatar 头像组件
<Avatar
size="large"
rounded
source={{ uri: 'https://randomuser.me/api/portraits/men/36.jpg' }}
/>
Avatar 组件支持:
- 图片头像
- 文字头像
- 图标头像
- 圆形/方形
- 不同尺寸(small, medium, large, xlarge)
3. Input 输入框组件
<Input
placeholder="With icon"
leftIcon={{ type: 'font-awesome', name: 'user' }}
/>
Input 组件支持:
- 左右图标
- 错误提示
- 占位符
- 多种输入类型
4. SearchBar 搜索栏组件
<SearchBar
placeholder="Type Here..."
onChangeText={(text) => setValue(text)}
value={value}
round
/>
SearchBar 支持圆形样式、清除按钮等。
5. Slider 滑块组件
<Slider
value={sliderValue}
onValueChange={setSliderValue}
maximumValue={1}
minimumValue={0}
step={0.1}
/>
Slider 组件支持自定义滑块样式和图标。
6. CheckBox 复选框组件
<CheckBox
title="Click Here"
checked={checked}
onPress={() => setChecked(!checked)}
/>
CheckBox 支持自定义图标和样式。
7. ListItem 列表项组件
<ListItem bottomDivider>
<Icon name={l} />
<ListItem.Content>
<ListItem.Title>{l}</ListItem.Title>
</ListItem.Content>
<ListItem.Chevron />
</ListItem>
ListItem 是构建列表的基础组件,支持左图标、右箭头等。
8. Icon 图标组件
<Icon name="home" type="font-awesome" size={30} />
Icon 组件支持多种图标库:
- font-awesome
- material
- material-community
- ionicons
- octicons
- zocial
- simple-line-icon
- feather
- antdesign
- entypo
- evilicons
9. ThemeProvider 主题提供者
const theme = createTheme({
lightColors: {
primary: '#2089dc',
secondary: '#3ac4fa',
},
mode: 'light',
});
<ThemeProvider theme={theme}>
{/* 你的应用组件 */}
</ThemeProvider>
ThemeProvider 允许你创建和应用自定义主题,支持亮色和暗色模式。
⚠️ 注意事项与最佳实践
1. 主题配置
- 在应用最外层使用 ThemeProvider 包裹
- 使用 createTheme 创建主题对象
- 支持 lightColors 和 darkColors 两套配色方案
2. 组件导入
// 带主题的组件
import { Button, Icon } from '@rneui/themed';
// 基础组件
import { Text } from '@rneui/base';
3. 图标库支持
react-native-elements 支持多种图标库,需要安装对应的依赖:
npm install @rneui/base @rneui/themed
4. 性能优化
- 对于大量列表,使用 React Native 的 FlatList 而不是手动渲染多个 ListItem
- 避免在 render 方法中创建新的样式对象
- 使用 React.memo 优化组件性能
5. 样式定制
每个组件都支持 style 和 containerStyle 属性:
<Button
title="Custom Style"
style={styles.buttonStyle}
containerStyle={styles.containerStyle}
/>
6. HarmonyOS 兼容性
react-native-elements 在 HarmonyOS 上完全兼容,无需额外配置。所有组件在三端都能正常工作。
🧪 测试验证
1. Android 平台测试
npm run android
测试要点:
- 检查所有组件是否正常渲染
- 验证主题颜色是否正确
- 测试交互功能(点击、滑动等)
2. iOS 平台测试
npm run ios
测试要点:
- 检查组件样式是否一致
- 验证动画效果
- 测试不同屏幕尺寸
3. HarmonyOS 平台测试
npm run harmony
测试要点:
- 验证组件渲染
- 检查主题应用
- 测试交互响应
4. 常见问题排查
问题 1: 图标不显示
- 确保已安装对应的图标库
- 检查图标名称和类型是否正确
问题 2: 主题不生效
- 确保使用 ThemeProvider 包裹应用
- 检查主题配置是否正确
问题 3: 样式不一致
- 检查各平台的样式属性支持情况
- 使用 Platform API 进行平台特定样式处理
📊 对比:原生组件 vs react-native-elements
| 特性 | 原生组件 | react-native-elements |
|---|---|---|
| 开箱即用 | ❌ | ✅ |
| 设计一致性 | ⚠️ 需要自己设计 | ✅ 统一设计 |
| 主题支持 | ❌ | ✅ |
| 图标集成 | ❌ | ✅ 多种图标库 |
| 文档完善 | ⚠️ | ✅ 详尽文档 |
| 社区支持 | ⚠️ | ✅ 活跃社区 |
| 性能 | ✅ | ⚠️ 稍有损耗 |
| 定制性 | ✅ 完全控制 | ⚠️ 受限于API |
📝 总结
通过集成 react-native-elements,我们为项目添加了一套完整的 UI 组件库。这个库提供了丰富的组件、统一的主题系统和跨平台的一致性,可以大大提升开发效率和用户体验。
关键要点回顾
- ✅ 安装依赖:
npm install @rneui/themed @rneui/base - ✅ 配置平台: 纯 JavaScript 库,无需手动配置原生代码
- ✅ 集成代码: 使用 ThemeProvider 和各种组件
- ✅ 主题定制: 使用 createTheme 创建自定义主题
- ✅ 测试验证: 确保三端表现一致
实际效果
- Android: 显示 Material Design 风格的组件
- iOS: 显示 iOS 风格的组件
- HarmonyOS: 显示 HarmonyOS 风格的组件
希望这篇教程能帮助你顺利集成 react-native-elements,提升应用的用户体验!
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)