基于HarmonyOS API 24 React Native跨平台鸿蒙开发实战系列:Image标签图片自适应显示(二),使用spectRatio控制组件的宽高比例

📅 2026/7/27 8:52:29 👁️ 阅读次数 📝 编程学习
基于HarmonyOS API 24 React Native跨平台鸿蒙开发实战系列:Image标签图片自适应显示(二),使用spectRatio控制组件的宽高比例

本文是基于HarmonyOS API 24的进行的React Native跨平台技术实战项目

React Native 跨端鸿蒙开发,行业简称 RNOH(React Native OpenHarmony),是社区 + 华为共建的适配层方案:把 Meta 的 React Native 框架完整移植到鸿蒙(HarmonyOS NEXT / OpenHarmony),让一套 React/JS/TS 代码,同时运行在Android、iOS、鸿蒙手机 / 平板 / PC多端,属于原生级跨端方案,区别于 WebView 套壳网页方案。

简单一句话:前端工程师不用学 ArkTS,用熟悉的 React 语法写业务,底层自动映射成鸿蒙 ArkUI 原生控件,打包成鸿蒙标准 hap 应用上架应用市场。

它的核心定位可以概括为:不改变 React/TypeScript 前端研发习惯,复用现有 RN 业务代码资产,依托鸿蒙系统底层接口做一层高性能中间适配层,将 JSX 组件、JS 业务逻辑映射为鸿蒙原生 ArkUI 控件,最终构建可在手机、平板、车机、智慧屏、PC 等全鸿蒙设备运行、支持上架华为应用市场的原生级应用。和 UniApp、WebView 套壳等网页类跨端方案有本质区别,RNOH 不依赖浏览器内核渲染页面,所有 UI 渲染、手势交互、视图层级全部交给鸿蒙系统原生图形引擎处理,不存在网页性能瓶颈、样式兼容偏差等问题。

兼容完整 React 生态、Hooks、JSX、RN 标准组件,前端工程师无需学习 ArkTS、ArkUI 声明式语法,仅需少量平台兼容代码即可完成多端适配;底层打通鸿蒙 NAPI、ArkUI C 底层接口,兼顾代码复用性与鸿蒙原生能力调用,核心面向存量 RN App 快速新增鸿蒙渠道,是前端团队切入鸿蒙生态最低成本的技术路线。


在React Native鸿蒙开发中实现图片自适应,确实与传统的定宽或定高方法有所不同。下面为您介绍几种有效的解决方案:

核心解决方案

1. 使用 aspectRatio 属性(推荐)

这是目前最稳定可靠的方法,通过设置宽高比来实现自适应

<Image source={{uri:'https://picsum.photos/400/600'}}style={{width:'100%',aspectRatio:1.5// 宽度:高度 = 1:1.5}}resizeMode="contain"/>

这种方法在平板、折叠屏等各种设备上都能正常显示,避免了屏幕尺寸获取不准确的问题。

2. Image组件基础用法

React Native的Image组件支持多种图片加载方式

‌加载网络图片:‌

<Image source={{uri:'https://example.com/image.jpg'}}style={{width:'100%',aspectRatio:1}}/>```加载本地图片:‌```js<Image source={require('./assets/image1.jpg')}style={{width:'100%',aspectRatio:0.75}}/>

3. 处理鸿蒙平台的多分辨率适配

在鸿蒙平台上,设备不会像Android那样自动加载@2x、@3x图片,需要手动处理:

// 根据设备像素比选择不同分辨率的图片 const pixelRatio = PixelRatio.get(); let imageSource; if (pixelRatio >= 3) { imageSource = require('./images/xxx@3x.png'); } else if (pixelRatio >= 2) { imageSource = require('./images/xxx@2x.png'); } else { imageSource = require('./images/xxx.png'); } <Image source={imageSource} style={{width: '100%', aspectRatio: 1}} />

实用建议

‌立即尝试‌:在您当前项目的图片组件中添加 aspectRatio 属性,结合 width: ‘100%’ 即可快速实现自适应效果。


import React from 'react'; import { View, Text, Dimensions, StyleSheet, Image } from 'react-native'; //获取屏幕的宽高 const screenWidth =Math.round( Dimensions.get('window').width); const screenHight =Math.round( Dimensions.get('window').height); const AppStyles = StyleSheet.create({ wrap: { width: '100%', height: screenHight, backgroundColor: '#85BDFF' }, title: { width: '100%', height: 72, fontFamily: 'OPPOSans, OPPOSans', fontWeight: 'normal', paddingTop: 50, fontSize: 36, color: '#304057', lineHeight: 72, textAlign: 'center', fontStyle: 'normal' }, banner: { paddingTop: 50, paddingRight: 32, paddingLeft: 32, }, bannerItem: { paddingTop: 10, display: 'flex', flexDirection:'row', alignItems: 'center', justifyContent: 'center', width: '50%', } }) function App() { return ( <View style={AppStyles.wrap}> <Text style={AppStyles.title}>鸿蒙ReactNative系统</Text> <View style={AppStyles.banner}> <View style={{display:'flex',flexDirection:'row',justifyContent:'space-between'}}> <View style={AppStyles.bannerItem}> <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image> <Text style={{paddingLeft: 4}}>实时业绩便捷查询</Text> </View> <View style={AppStyles.bannerItem}> <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image> <Text style={{paddingLeft: 4}}>订单状态轻松把控</Text> </View> </View> <View style={{display:'flex',flexDirection:'row',justifyContent:'space-between'}}> <View style={AppStyles.bannerItem}> <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image> <Text style={{paddingLeft: 4}}>宣传数据全程管理</Text> </View> <View style={AppStyles.bannerItem}> <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image> <Text style={{paddingLeft: 4}}>海量素材一站转发</Text> </View> </View> </View> <Image style={{width:289, aspectRatio: 0.6}} source={require('./images/login-bg.png')}></Image> </View> ); } export default App;

可以看到在使用aspectRatio之后,表示React Native中的aspectRatio属性用于控制组件的宽高比,通过设置一个数字值(如1表示正方形),可自动计算未指定的维度(宽度或高度),从而实现自适应布局,但是貌似会自动截取图片。


接下来我们再次修改aspectRatio让图片居中到页面。

核心功能

  • 定义宽高比:设置aspectRatio: 1时,组件宽度和高度相等;设置aspectRatio: 2时,宽度是高度的两倍 。
  • 自动计算未指定维度:若仅指定宽度或高度,另一维度会根据宽高比自动调整 。

使用场景

  • 图片展示:结合宽度或高度设置,无需手动计算另一维度 。
  • 响应式布局:确保组件在不同容器中保持比例,避免变形 。

注意事项

  • 与Flex布局的兼容性:在Flex容器中使用时,可能影响justifyContent等对齐属性,需通过调整父容器或子组件样式解决 。
  • 优先级:若同时设置宽度、高度和宽高比,宽高比会覆盖其他尺寸约束 。

安装DevEco Studio程序


选择目标安装目录:


设置环境变量,但是需要重启一下:


新建一个空白模板:


设置API为24的模板项目:

初始化项目,自动下载相关依赖:


完整代码:

import React from 'react'; import { View, Text, Dimensions, StyleSheet, Image } from 'react-native'; //获取屏幕的宽高 const screenWidth =Math.round( Dimensions.get('window').width); const screenHight =Math.round( Dimensions.get('window').height); const AppStyles = StyleSheet.create({ wrap: { width: '100%', height: screenHight, backgroundColor: '#85BDFF' }, title: { width: '100%', height: 72, fontFamily: 'OPPOSans, OPPOSans', fontWeight: 'normal', paddingTop: 50, fontSize: 36, color: '#304057', lineHeight: 72, textAlign: 'center', fontStyle: 'normal' }, banner: { paddingTop: 50, paddingRight: 32, paddingLeft: 32, }, bannerItem: { paddingTop: 10, display: 'flex', flexDirection:'row', alignItems: 'center', justifyContent: 'center', width: '50%', } }) function App() { return ( <View style={AppStyles.wrap}> <Text style={AppStyles.title}>鸿蒙ReactNative系统</Text> <View style={AppStyles.banner}> <View style={{display:'flex',flexDirection:'row',justifyContent:'space-between'}}> <View style={AppStyles.bannerItem}> <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image> <Text style={{paddingLeft: 4}}>实时业绩便捷查询</Text> </View> <View style={AppStyles.bannerItem}> <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image> <Text style={{paddingLeft: 4}}>订单状态轻松把控</Text> </View> </View> <View style={{display:'flex',flexDirection:'row',justifyContent:'space-between'}}> <View style={AppStyles.bannerItem}> <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image> <Text style={{paddingLeft: 4}}>宣传数据全程管理</Text> </View> <View style={AppStyles.bannerItem}> <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image> <Text style={{paddingLeft: 4}}>海量素材一站转发</Text> </View> </View> </View> <Image style={{width:289, aspectRatio: 0.6, display: 'flex', alignSelf: 'center'}} source={require('./images/login-bg.png')}></Image> </View> ); } export default App;


当只设置宽度时,高度会根据比例自动计算;反之亦然。这比传统的百分比 padding 技巧更简洁直观,实用建议‌:在开发图片展示组件时,直接使用 aspectRatio 替代复杂的宽高计算,能让你的布局代码更简洁且易于维护。