1. 程式人生 > >React Native 載入圖片的正確姿勢和遇到的一些么蛾子

React Native 載入圖片的正確姿勢和遇到的一些么蛾子

一、載入圖片的正確姿勢

做過原生開發和在使用App時比較注重使用者體驗的都會注意到“List中載入過程中會出現跟業務相關的Loading圖,當圖片載入成功之後會消失;當圖片載入失敗之後會展示預設的error圖”,針對這個問題,自己嘗試著在做RN的時候優化一下這些細節

RN的提供的圖片元件Image顯然是沒有提供這些優化的介面,但值得高興的是,整個元件提供了圖片載入的完成周期:

onLoadStart:當開始載入圖片呼叫該方法
onLoadEnd:當載入完成回撥該方法,不管圖片載入成功還是失敗都會呼叫該方法
onLoad:當圖片載入成功之後,回撥該方法
onError:該屬性要賦值一個function,當加載出錯執行賦值的這個方法

拿到生命週期之後我們為圖片載入定義了三個狀態:載入中、載入成功、載入失敗

接下來,我們就對官方的Image元件進行一下封裝

import React, { Component } from 'react'
import { View, Image, Animated, Easing, ViewPropTypes, StyleSheet, Platform } from 'react-native'
import { Colors } from '../Themes/index'
import Icon from '../Fonts/iconfont'

export default class
LoadImage extends Component {
static propTypes = { style: React.PropTypes.oneOfType([ ViewPropTypes.style, React.PropTypes.number ]), source: React.PropTypes.object.isRequired, defaultSource: React.PropTypes.oneOfType([ React.PropTypes.object, React.PropTypes.number ]) } constructor (props) { super
(props) this.state = { loadStatus: 'pending', backgroundColor: new Animated.Value(0) } } componentWillUnmount () { if (undefined !== this.backgroundColorAnimated) this.backgroundColorAnimated.stop() } /** * 開始載入 */ onLoadStart () { // 配置載入動畫 this.backgroundColorAnimated = Animated.sequence([ Animated.timing(this.state.backgroundColor, { toValue: 1, easing: Easing.ease, duration: 400 }), Animated.timing(this.state.backgroundColor, { toValue: 0, easing: Easing.in, duration: 400 }) ]) this.backgroundColorAnimated.start(() => { this.state.loadStatus === 'pending' && this.onLoadStart() }) } /** * 載入結束 */ onLoadEnd () { // if (undefined !== this.backgroundColorAnimated) this.backgroundColorAnimated.stop() } /** * 載入成功 */ handleImageLoaded () { this.setState({ loadStatus: 'success' }) } /** * 載入失敗 * @param {*} error */ handleImageErrored (error) { console.log(error) this.setState({ loadStatus: 'error' }) } /** * 渲染載入中介面 */ renderPending () { let { style } = this.props return ( <Animated.View style={[style, { position: 'absolute', backgroundColor: this.state.backgroundColor.interpolate({ inputRange: [0, 1], outputRange: ['#F7F9FB', Colors.C7] }) }]} /> ) } /** * 渲染載入失敗介面 */ renderError () { let { style, defaultSource } = this.props if (typeof style === 'number') { style = StyleSheet.flatten(style) } let iconSize = Math.min(style.height, style.width) / 3 return ( defaultSource ? <Image source={defaultSource} style={[{ position: 'absolute' }, style]} /> : <View style={[{ justifyContent: 'center', backgroundColor: Colors.C7, position: 'absolute', alignItems: 'center' }, style]}> <Icon name='image' size={iconSize} color={Colors.C6} /> </View> ) } render () { let { style, source } = this.props let { loadStatus } = this.state // 相容 uri為null的情況 if (source.hasOwnProperty('uri') && typeof source['uri'] !== 'string') { source = { ...source, uri: '' } } // 相容Androud無法對空字串進行處理情況 if (Platform.OS === 'android' && source.hasOwnProperty('uri') && !source['uri']) { source = { ...source, uri: ' ' } } return ( <View style={style}> <Image source={source} style={style} onLoadStart={this.onLoadStart.bind(this)} onLoadEnd={this.onLoadEnd.bind(this)} onLoad={this.handleImageLoaded.bind(this)} onError={this.handleImageErrored.bind(this)} /> {loadStatus === 'pending' && this.renderPending()} {loadStatus === 'error' && this.renderError()} </View> ) } }

原理就是在載入未成功之前講各個狀態的展示圖片通過絕對定位覆蓋列表展示圖片,PS:圖片佔位大小wu保持一致

最新版本的程式碼做了幾點優化
1、pending樣式採用“呼吸背景”的動畫
2、生命週期控制更加完善
3、增加對uri = null的相容(null會拋異常,uri required string)
4、增加Android對uri為空字串的相容,在android下,uri為空串時不會在載入生命生期中呼叫onLoadEnd等方法

二、正常使用注意資訊

1、 [email protected] [email protected] 是怎麼回事?

一開始見到這樣的圖片以為是不同大小的,嘻嘻嘻,開啟真的確實不一樣大,但是看了文件之後才發現,這個是針對不同螢幕精度的做法

這麼用就OK了

2、require() 和 {uri: ”}

文件原文:uri是一個表示圖片的資源標識的字串,它可以是一個http地址或是一個本地檔案路徑(使用require(相對路徑)來引用)

大致掃了一下文件,知道require() 是載入本地資源的,{uri: ”} 是載入網路資源的,但是。 注意文件的細節,require()只能載入靜態資源,說白了就是本地的相對、或者絕對地址,是一個string型別的,比如’../Image/success.png’,但是,如果你把這個string賦值給了一個變數再通過require()引用肯定是不行的,這時只能通過{uri: }引用

三、 待續

相關推薦

React Native 載入圖片正確姿勢遇到的一些蛾子

一、載入圖片的正確姿勢 做過原生開發和在使用App時比較注重使用者體驗的都會注意到“List中載入過程中會出現跟業務相關的Loading圖,當圖片載入成功之後會消失;當圖片載入失敗之後會展示預設的error圖”,針對這個問題,自己嘗試著在做RN的時候優化一下這

Android React Native載入圖片資源的正確姿勢

在這篇文章中Android React Native的使用細節問題提到了 圖片使用的問題,也提到了無論用哪種方法都不能載入app內部的圖片資源的問題,當時的程式碼是這樣子的 <Image source={ require('image!icon') } />

react native載入多個jsbundle(assets其他目錄)

在使用ReactInstanceManager.Builder構建一個ReactInstanceManager例項的時候只能傳入一個bundle,setBundleAssetName和setJSBundleFile分別對應從assets和從一個檔案路徑載入Bundle。有時需要將業務程式碼和通用

React-Native載入網路圖片的問題

RN還需要管載入圖片嗎?facebook已經實現啦快取圖片, 如果你用多點圖片測試下,就會發現並不是如此。 listview中facebook封裝的不錯,記憶體消耗一隻是平穩的,listView顯

React native 之android的圖示啟動圖片

哎哎呀呀,上篇說到了react native的IOS的圖示和啟動圖片的設定,其實最主要的是尺寸!相應的尺寸設定好了以後就不會報錯了!ok~這篇說的是React native的android的圖示和啟動頁面!!!!!1.圖示:其實android的圖示設定很簡單,一般情況下只需要替換就可以了(當然你也可以不去替換

React Native圖片載入方式

      在做APP的時候,遇到了要載入圖片的問題,本來以為很簡單,,但是知道真相的我眼淚掉下來。在此記錄一下。。 一、本地圖片的載入       如上圖:./代表當前檔案,相當於是在本地專案根據目錄找到該圖片即可。問題是需要注意,圖片是require

react native獲取螢幕的寬度高度

var Dimensions = require('Dimensions'); var {width,height} = Dimensions.get("window");//第一種寫法 var width1 = Dimensions.get('window').width//第二種寫法 expor

在Flutter中嵌入Native元件的正確姿勢是...

作者:閒魚技術-塵蕭 引言 在漫長的從Native向Flutter過渡的混合工程時期,要想平滑地過渡,在Flutter中使用Native中較為完善的控制元件會是一個很好的選擇。本文希望向大家介紹AndroidView的使用方式以及在此基礎之上拓展的雙端嵌入Native元件的解決方案。 1. 使用教程

react-native-vector-icons的安裝使用

react-native-vector-icons是一個React Native 專案使用最廣泛的向量圖示圖示庫,使用簡單,內容豐富。 react-native-vector-icons官網 react-native-vector-icons圖示展示列表 使用react-native-vector-icon

React Native 結合ScrollableTab、RefreshControlFlatList實現新聞分類列表

正好剛開始學RN,熟悉一下控制元件和基本使用。 涉及的知識點: 1、fetch網路請求,get 拼接引數,解析json。 2、ScrollableTabView、ScrollableTabBar 分類佈局。 3、FlatList 資料列表。 4、Navigation

關於Android載入圖片時的OOM的一些解決方法優化

1、通過強引用和弱引用以及LRU演算法。 private static final int HARD_CACHE_CAPACITY = 20;//強引用的bitmap的數量 //為了提高圖片的利用率,通過單鏈表實現先進先出,將老的圖片移到軟引用裡面儲存 private st

react-native圖片轉化base64字串

1).匯入’react-native-fs’ import RNFS from 'react-native-fs'; 2).通過react-native-fs包中的readFile()獲取b

react native開發中eslint配置初始化

先簡單介紹一下mac系統環境下,eslint的配置。 首先開啟命令列工具,cd到專案根目錄下。 一次輸入命令並等待下載完成。 npm install eslint --save-dev npm ins

關於React-native裡Android原生模組元件的寫法

原生模組就是把Android裡的API匯出來給JS呼叫,說簡單一點,就是讓自己寫的Java函式能夠在React Native的js程式碼裡呼叫。比如一些實現高效能的、多執行緒的程式碼,還有譬如圖片處理、資料庫、或者各種高階擴充套件等等。 舉個栗子: Toas

React Native入門篇—react-native-splash-screen的安裝配置

注意:未經允許不可私自轉載,違者必究 React Native官方文件:https://reactnative.cn/docs/getting-started/ react-native-splash-screen官方文件:https://github.com/crazycod

react-native在windows下安裝配置

zhu’yi本次安裝時基於windows7系統,32位,在虛擬機器上面安裝的。 1、安裝JDK,配置環境變數。 下載JDK,然後配置環境變數JAVA_HOME,還是按照正規路徑來,不然編譯時候找不到就尷尬了。 然後將%JAVA_HOME%\bin;%J

React Native開源圖片縮放處理元件

尊重版權,轉載請註明出處 專案介紹 該元件進行封裝了Android平臺PhotoView和Universal-image-loader元件,進行實現影象縮放等功能。不過只是適配Android平臺 剛建立的React Native技術交流3群(496508742)歡迎各位大牛,React Nati

Phaserjs基礎教程第二節:載入圖片、文字動畫

遊戲場景的建立是遊戲開發的基礎,而遊戲場景又是由各種圖片、模型、文字等構成的,我們本節就來學習怎麼載入資源到遊戲場景中。       一、載入圖片:首先,我們載入一張簡單的圖片,程式碼如下:var game = newPhaser.Game(800, 600, Phaser.

React-Native新列表元件FlatListSectionList學習 | | 聯動列表實現

React-Native在0.43推出了兩款新的列表元件:FlatList(高效能的簡單列表元件)和SectionList(高效能的分組列表元件). http://www.cnblogs.com/shaoting/p/7069312.html 從官方上它們都支援常用

React Native圖片輪播

圖片輪播在App開發中經常使用,這裡圖片輪播使用的是第三方元件react-native-swiper, 我們啟動npm命令列,在專案的根目錄使用如下命令安裝模組。 $ npm install react-native-swiper --save $ npm