RN Image 不能显示 https 图片处理

本文介绍如何在React Native中处理RNImage组件无法显示HTTPS图片的问题。通过使用react-native-fetch-blob库将HTTPS图片转换为Base64编码,从而实现显示。详细步骤包括配置请求选项和读取文件为Base64字符串。

RN Image 不能显示https 图片,但是 http的能够正常处理。

方法: 1. 把https 直接改成 http (可能不行,可能可以,我碰到的不行)

方法: 2. 把https 转成base64 后显示 (以下代码就是)

import React, {Component}from 'react';
import {Image, TouchableOpacity, StyleSheet,Platform} from 'react-native';
import {Actions}  from 'react-native-router-flux';
import RNFetchBlob from 'react-native-fetch-blob';

export default class GridItem extends Component {

    state = {
        base64Data: ''
    }

    componentDidMount() {
        const { item: { uri } } = this.props;
        if (!uri || uri.indexOf('https') === -1) {
            return;
        }

        RNFetchBlob.config(Platform.OS === 'android' ? {
                trusty: true,
                fileCache: true
            } : {fileCache: true})
            .fetch('GET', uri)
            .then((resp) => {
                return resp.readFile('base64')
            })
            .then(base64Data=> {
                this.setState({
                    base64Data: 'data:image/png;base64,' + base64Data
                })
            })
    }

    _selectPhoto = () => {

        const {item, selectPhoto} = this.props
        selectPhoto(item)
    }

    _deletePhoto = () => {

        const {item, deletePhoto} = this.props
        deletePhoto(item)
    }

    _ManagePhotos = ()=> {
        const {item, deletePhoto} = this.props
        console.log(item)
        Actions.ManagePhotos({item: item, deletePhoto: deletePhoto});
    }

    render() {
        let props;
        let { item } = this.props
        let isAddPhoto = item.uri.indexOf('photo_add') !== -1;
        if (isAddPhoto || item.uri.indexOf('https') === -1) {
            props = this.props;
        } else {
            props = Object.assign({}, this.props, {item: {uri: this.state.base64Data}});
        }
        return <TouchableOpacity onPress={isAddPhoto?this._selectPhoto:this._ManagePhotos}>
            {isAddPhoto ?
                <Image source={require('./img/photo_add.png')} style={styles.photo}/> :
                <Image source={{uri: props.item.uri}} style={styles.photo}/>
            }
        </TouchableOpacity>
    }
}


const styles = StyleSheet.create({
    photo: {
        height: 80,
        width: 80,
        marginRight: 4,
    },
})
<think>好的,用户问的是关于如何在React Native中显示加载图片时的loading图。首先,我需要回忆一下React Native的相关知识,尤其是图片加载的处理方法。React Native的Image组件在加载图片时,尤其是网络图片,可能需要一定时间,这时候显示一个占位图或者loading动画可以提升用户体验。 首先,用户可能需要知道Image组件自带的属性,比如`defaultSource`(在iOS上)或者`loadingIndicatorSource`(仅Android),但这些可能有限制或者平台差异。例如,`loadingIndicatorSource`只适用于Android的网络图片,而iOS可能需要其他方法。 接下来,用户可能需要更跨平台的解决方案。这时候,可以考虑使用第三方库,比如`react-native-fast-image`,它提供了更好的缓存和加载控制,包括placeholder的支持。但用户可能不想引入额外依赖,所以可能需要纯React Native的实现。 然后,考虑如何监听图片加载的状态。Image组件有`onLoadStart`、`onLoad`、`onLoadEnd`和`onError`等事件。可以利用这些事件来控制loading状态的显示。例如,当开始加载时显示loading图,加载完成后隐藏。 另外,图片加载过程中可能需要显示一个本地的loading图,比如一个旋转的指示器或者占位图。这时候需要结合状态管理,使用useState来跟踪是否正在加载。 还需要考虑样式问题,确保loading图和实际图片的位置和尺寸一致,避免布局跳动。可能需要绝对定位,将loading图覆盖在Image上方,加载完成后隐藏。 可能还需要处理加载失败的情况,显示错误占位图。但用户当前的问题主要是loading图,所以可能先专注于加载中的状态。 综上,步骤大概是:使用Image组件的加载事件,管理加载状态,在加载时显示占位图或ActivityIndicator,加载完成后显示实际图片。同时注意跨平台的一致性和样式调整。 现在需要检查是否有遗漏的点,比如网络图片的缓存问题,或者图片组件在列表中的性能优化。但用户的问题比较基础,可能不需要深入这些方面。重点放在如何实现loading效果,代码示例是否清晰,是否需要使用第三方库等。 最后,确保回答结构清晰,分步骤说明,提供代码示例,并指出不同方法的优缺点,比如使用第三方库的好处和纯React Native的实现限制。</think>在 React Native 开发中,为网络图片添加加载状态指示是提升用户体验的常见需求。以下是实现 Loading 图的两种典型方案: $$ \begin{cases} \text{方案一:使用 Image 原生属性(有限制)} \\ \text{方案二:自定义加载状态(推荐)} \end{cases} $$ --- ### 一、方案一:使用内置属性(平台受限) ```jsx // Android 专用 loading 指示器 <Image source={{ uri: 'https://example.com/remote-image.jpg' }} loadingIndicatorSource={require('./local-loading.png')} // 仅 Android 生效 /> // iOS 默认占位图(本地资源) <Image source={{ uri: 'https://example.com/remote-image.jpg' }} defaultSource={require('./local-placeholder.png')} // 仅 iOS 生效 /> ``` **缺点**:平台实现不统一,功能受限 --- ### 二、方案二:自定义加载状态(推荐实现) ```jsx import { useState } from 'react'; import { View, Image, ActivityIndicator } from 'react-native'; const LoadingImage = ({ src }) => { const [isLoading, setIsLoading] = useState(true); const [hasError, setHasError] = useState(false); return ( <View style={{ position: 'relative' }}> {/* 加载状态指示器 */} {isLoading && ( <View style={{ position: 'absolute', zIndex: 1 }}> <ActivityIndicator size="small" color="#999" /> {/* 或使用本地图片 */} {/* <Image source={require('./loading.gif')} /> */} </View> )} {/* 主图片 */} <Image source={{ uri: src }} style={{ opacity: isLoading ? 0.5 : 1 }} onLoadStart={() => { setIsLoading(true); setHasError(false); }} onLoad={() => setIsLoading(false)} onError={() => setHasError(true)} /> {/* 错误状态 */} {hasError && <Image source={require('./error-placeholder.png')} />} </View> ); }; ``` --- ### 三、进阶优化方案 1. **使用 FastImage(第三方库)** ```bash npm install react-native-fast-image ``` ```jsx import FastImage from 'react-native-fast-image'; <FastImage source={{ uri: 'https://example.com/image.jpg', priority: FastImage.priority.normal, }} resizeMode={FastImage.resizeMode.contain} onLoadStart={() => console.log('开始加载')} onLoadEnd={() => console.log('加载结束')} /> ``` **优点**:更好的缓存机制和加载控制 2. **骨架屏效果** 使用 `react-native-shimmer` 库实现动态渐变效果: ```jsx import Shimmer from 'react-native-shimmer'; <Shimmer> <Image /* 你的图片组件 */ /> </Shimmer> ``` --- ### 四、实现要点总结 1. 使用 `onLoadStart`/`onLoad`/`onError` 生命周期事件 2. 通过 `position: absolute` 实现叠加布局 3. 建议组合使用 `ActivityIndicator` 与渐变动画 4. 重要图片建议预加载: ```jsx Image.prefetch('https://example.com/important-image.jpg'); ``` 通过合理使用这些方案,可以有效提升图片加载时的用户体验,建议根据具体场景选择最适合的实现方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值