一個(gè) react 的組件用以顯示不同類型的圖片,包括網(wǎng)絡(luò)圖片,靜態(tài)資源,臨時(shí)的本地圖片,還有本地磁盤的圖片,比如手機(jī)照片。
舉例:
renderImages: function() { return ( <View> <Image style={styles.icon} source={require('image!myIcon')} /> <Image style={styles.logo} source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}} /> </View> ); },
onLayout 函數(shù)
在進(jìn)行裝載和布局改變的時(shí)候使用{nativeEvent: {layout: {x, y, width, height}}}
調(diào)用。
resizeMode 枚舉 ('cover', 'contain', 'stretch')
當(dāng)幀與原始圖像尺寸不匹配時(shí)用于確定如何調(diào)整圖像的大小。
source {uri: string},編號 uri
是一個(gè)代表圖片資源標(biāo)識符的字符串,它可以是 http 地址、 本地文件路徑或靜態(tài)圖像資源的名稱 (它被包含在 require('image!name')
函數(shù)中) 。
style 樣式
Flexbox......
Transforms...
resizeMode Object.keys(ImageResizeMode)
backgroundColor 字符串
borderColor 字符串
borderWidth 數(shù)字
borderRadius 數(shù)字
overflow 枚舉('visible', 'hidden')
tintColor 字符串
opacity 數(shù)字
testID 字符串 一個(gè)在 UI 自動(dòng)測試腳本中使用此元素的唯一標(biāo)識符。
ios
accessibilityLabel 字符串
在用戶與圖像交互時(shí),該文本會(huì)由屏幕閱讀器讀取。
ios
accessible 布爾值
當(dāng)為 true 的時(shí)候,指示圖像是可訪問的元素。
ios
capInsets {top: number, left: number, bottom: number, right: number}
當(dāng)圖像的大小被重新調(diào)整時(shí),由 capInsets 指定的角落的大小將保持在一個(gè)固定的值,但中心內(nèi)容和圖像的邊界將被拉伸。這用于創(chuàng)建可調(diào)整大小的圓形按鈕、 陰影和其他可調(diào)整大小的資源。更多關(guān)于蘋果的文檔請點(diǎn)擊此處。
ios
defaultSource {uri: string}
在下載最終圖像并且網(wǎng)絡(luò)斷開的時(shí)候用來顯示的靜態(tài)圖像。
ios
onError 函數(shù)
在加載錯(cuò)誤的時(shí)候使用 {nativeEvent: {error}}
進(jìn)行調(diào)用。
ios
onLoadEndr 函數(shù)
當(dāng)完全加載成功時(shí)進(jìn)行調(diào)用。
ios
onLoadEnd 函數(shù)
不管加載成功還是失敗都會(huì)調(diào)用。
ios
onLoadStart 函數(shù)
加載成功的時(shí)候調(diào)用。
ios
onProgress 函數(shù)
在下載進(jìn)程中使用 {nativeEvent: {loaded, total}}
進(jìn)行調(diào)用。
在項(xiàng)目的進(jìn)程中,添加并且移除和處理那些在應(yīng)用程序不是經(jīng)常使用的圖片是很常見的情況。為了處理這種情況,我們需要找到一個(gè)方法來靜態(tài)地定位那些被用在應(yīng)用程序里的圖片。因此,我們使用了一個(gè)標(biāo)記器。唯一允許的指向 bundle 里的圖片的方法就是在源文件中遍歷地搜索 require('image!name-of-the-asset')
。
// GOOD<Image source={require('image!my-icon')} />// BADvar icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';<Image source={require('image!' + icon)} />// GOOD var icon = this.props.active ? require('image!my-icon-active') : require('image!my-icon-inactive');<Image source={icon} />
當(dāng)主要的代碼執(zhí)行到這里,你就可以做一些有趣的事情,比如自動(dòng)將那些用于應(yīng)用程序的 assets 打包。注意,這些代碼不是強(qiáng)制實(shí)施的,但不代表將來也不會(huì)。
NOTE: 生成應(yīng)用程序所需的新資源
無論在什么時(shí)候,您想把新的資源添加到
Images.xcassets
中,您都需要在使用它之前通過 Xcode 來重新構(gòu)建您的應(yīng)用程序 — — 僅在模擬器內(nèi)重新加載它是不夠的。
這一進(jìn)程正在被改進(jìn),不久就會(huì)提供更好的工作流程。
將您的圖像作為位圖畫板添加到 android 項(xiàng)目中(<yourapp>/android/app/src/main/res
)。 為了給您的 assets 文件提供不同的分辨率,使用 配置限定符進(jìn)行檢查。 通常情況下,您將想要把您的 assets 文件放在下列目錄 (如果它們不存在,那么在 res
下創(chuàng)建它們):
drawable-mdpi
(1x)
drawable-hdpi
(1.5x)
drawable-xhdpi
(2x)
drawable-xxhdpi
(3x)
如果您的 asset 文件丟失了一種分辨率,那么 Android 將采取下一個(gè)最好的分辨率并且為您調(diào)整它的大小。
NOTE: 生成應(yīng)用程序所需的新資源
無論在什么時(shí)候您把新的資源添加到您的畫板中您都需要在使用它之前通過運(yùn)行
react-native run-android
重新構(gòu)建您的應(yīng)用程序 - 僅重新加載 JS 是不夠的。
這一進(jìn)程正在被改進(jìn),不久就會(huì)提供更好的工作流程。
在您進(jìn)行編譯的時(shí)候,許多您的應(yīng)用程序中需要展示的圖片都不能使用,或者你會(huì)想要通過加載一些動(dòng)態(tài)圖片來保持二進(jìn)制大小在較低的狀態(tài)。不像靜態(tài)資源那樣,您將需要手動(dòng)指定圖像的尺寸。
// GOOD<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}} style={{width: 400, height: 400}} />// BAD<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}} />
請?jiān)?nbsp;CameraRoll 中查看使用 Images.xcassets
之外的本地資源示例 。
iOS 的相片冊可以讓你將同一張圖片保存為不同的尺寸,對于選擇那張接近你想要尺寸的圖片來說,這很重要。你不會(huì)想用一張 3264x2448 分辨率的圖片作為資源來顯示一個(gè) 200x200 的縮略圖。如果確實(shí)有符合你要求的尺寸, React Native 會(huì)自動(dòng)選擇它,否則它會(huì)使用第一張比特定尺寸大 50% 的圖片來避免重新定義尺寸時(shí)帶來的模糊失真。這些工作 React Native 自動(dòng)幫你完成了,所以你不必再自己編寫乏味和容易出錯(cuò)的代碼。
在瀏覽器中 如果你不給一個(gè)圖像規(guī)定大小,那么瀏覽器會(huì)呈現(xiàn)一個(gè) 0x0 的元素、 隨后下載圖像,然后再以正確的尺寸呈現(xiàn)圖像。這種行為最大的問題是,您的 UI 會(huì)在正在加載的圖像四周跳動(dòng),這會(huì)造成一個(gè)非常糟糕的用戶體驗(yàn)。
在 React Native 中故意不實(shí)施該行為。它的目的是讓開發(fā)人員可以提前知道遠(yuǎn)程圖像的尺寸 (或圖形比例),我們認(rèn)為這樣做的話可以實(shí)現(xiàn)更好的用戶體驗(yàn)。通過使用 require('image!x')
語法從應(yīng)用程序包中加載的靜態(tài)圖片可以自動(dòng)的調(diào)整大小,因?yàn)樗鼈兊某叽缭诎惭b時(shí)立即可用。
例如,上述使用 'require('image!logo')' 屏幕截圖的結(jié)果:
{"__packager_asset":true,"isStatic":true,"path":"/Users/react/HelloWorld/iOS/Images.xcassets/react.imageset/logo.png","uri":"logo","width":591,"height":573}
在 React Native 中,一個(gè)有趣的決定是 src
特性將會(huì)被命名為 source
,并且不作為一個(gè)字符串而是一個(gè) uri
特性的對象類型。
<Image source={{uri: 'something.jpg'}} />
站在底層來看,這樣做的原因是它允許將元數(shù)據(jù)依附到這個(gè)對象中。舉個(gè)例子,你正在使用 require('image!icon')
,我們將添加 isStatic
作為一個(gè) flag 來標(biāo)識本地文件(不要依賴這例子,將來這可能會(huì)改變?。_@在將來同時(shí)也會(huì)成為可能,比如我們可能會(huì)支持子畫面,并用它來取代輸出 {uri: ...}
,我們可以輸出 {uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}
同時(shí)支持在所有已經(jīng)存在的網(wǎng)站中透明地顯示子畫面。
在用戶角度上,這會(huì)讓你用有用的特性比如圖片的幾何尺寸來注釋對象類型,從而計(jì)算出將要顯示出來的尺寸。盡情地使用這種數(shù)據(jù)類型來儲(chǔ)存你的圖片吧。
一個(gè)對于 web 開發(fā)者們很常見的需求是 background-image
。這種情況下,創(chuàng)建一個(gè)簡單的 <Image>
組件然后將它作為子 layer 添加到你想要添加的 layer 上面。
return ( <Image source={...}> <Text>Inside</Text> </Image>);
圖片的解析會(huì)花費(fèi)很多的時(shí)間。這是導(dǎo)致網(wǎng)頁的幀數(shù)下降的其中一個(gè)重要的原因,因?yàn)榻馕龉ぷ鲿?huì)被執(zhí)行在主線程中。在 React Native 中,圖片的解析會(huì)在不同的線程中執(zhí)行。在實(shí)際操作中,你已經(jīng)處理好這種情況,當(dāng)圖片還沒有下載完成,因此需要將 placeholder 顯示出來,這不用你寫任何代碼。
'use strict'; var React = require('react-native'); var { Image, StyleSheet, Text, View, ActivityIndicatorIOS } = React; var ImageCapInsetsExample = require('./ImageCapInsetsExample'); var NetworkImageExample = React.createClass({ watchID: (null: ?number), getInitialState: function() { return { error: false, loading: false, progress: 0 }; }, render: function() { var loader = this.state.loading ? <View style={styles.progress}> <Text>{this.state.progress}%</Text> <ActivityIndicatorIOS style={{marginLeft:5}}/> </View> : null; return this.state.error ? <Text>{this.state.error}</Text> : <Image source={this.props.source} style={[styles.base, {overflow: 'visible'}]} onLoadStart={(e) => this.setState({loading: true})} onError={(e) => this.setState({error: e.nativeEvent.error, loading: false})} onProgress={(e) => this.setState({progress: Math.round(100 * e.nativeEvent.loaded / e.nativeEvent.total)})} onLoad={() => this.setState({loading: false, error: false})}> {loader} </Image>; } }); exports.displayName = (undefined: ?string); exports.framework = 'React'; exports.title = '<Image>'; exports.description = 'Base component for displaying different types of images.'; exports.examples = [ { title: 'Plain Network Image', description: 'If the `source` prop `uri` property is prefixed with ' + '"http", then it will be downloaded from the network.', render: function() { return ( <Image source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}} style={styles.base} /> ); }, }, { title: 'Plain Static Image', description: 'Static assets should be required by prefixing with `image!` ' + 'and are located in the app bundle.', render: function() { return ( <View style={styles.horizontal}> <Image source={require('image!uie_thumb_normal')} style={styles.icon} /> <Image source={require('image!uie_thumb_selected')} style={styles.icon} /> <Image source={require('image!uie_comment_normal')} style={styles.icon} /> <Image source={require('image!uie_comment_highlighted')} style={styles.icon} /> </View> ); }, }, { title: 'Error Handler', render: function() { return ( <NetworkImageExample source={{uri: 'http://TYPO_ERROR_facebook.github.io/react/img/logo_og.png'}} /> ); }, platform: 'ios', }, { title: 'Image Download Progress', render: function() { return ( <NetworkImageExample source={{uri: 'http://facebook.github.io/origami/public/images/blog-hero.jpg?r=1'}}/> ); }, platform: 'ios', }, { title: 'Border Color', render: function() { return ( <View style={styles.horizontal}> <Image source={smallImage} style={[ styles.base, styles.background, {borderWidth: 3, borderColor: '#f099f0'} ]} /> </View> ); }, platform: 'ios', }, { title: 'Border Width', render: function() { return ( <View style={styles.horizontal}> <Image source={smallImage} style={[ styles.base, styles.background, {borderWidth: 5, borderColor: '#f099f0'} ]} /> </View> ); }, platform: 'ios', }, { title: 'Border Radius', render: function() { return ( <View style={styles.horizontal}> <Image style={[styles.base, {borderRadius: 5}]} source={fullImage} /> <Image style={[styles.base, styles.leftMargin, {borderRadius: 19}]} source={fullImage} /> </View> ); }, }, { title: 'Background Color', render: function() { return ( <View style={styles.horizontal}> <Image source={smallImage} style={styles.base} /> <Image style={[ styles.base, styles.leftMargin, {backgroundColor: 'rgba(0, 0, 100, 0.25)'} ]} source={smallImage} /> <Image style={[styles.base, styles.leftMargin, {backgroundColor: 'red'}]} source={smallImage} /> <Image style={[styles.base, styles.leftMargin, {backgroundColor: 'black'}]} source={smallImage} /> </View> ); }, }, { title: 'Opacity', render: function() { return ( <View style={styles.horizontal}> <Image style={[styles.base, {opacity: 1}]} source={fullImage} /> <Image style={[styles.base, styles.leftMargin, {opacity: 0.8}]} source={fullImage} /> <Image style={[styles.base, styles.leftMargin, {opacity: 0.6}]} source={fullImage} /> <Image style={[styles.base, styles.leftMargin, {opacity: 0.4}]} source={fullImage} /> <Image style={[styles.base, styles.leftMargin, {opacity: 0.2}]} source={fullImage} /> <Image style={[styles.base, styles.leftMargin, {opacity: 0}]} source={fullImage} /> </View> ); }, }, { title: 'Nesting', render: function() { return ( <Image style={{width: 60, height: 60, backgroundColor: 'transparent'}} source={fullImage}> <Text style={styles.nestedText}> React </Text> </Image> ); }, }, { title: 'Tint Color', description: 'The `tintColor` style prop changes all the non-alpha ' + 'pixels to the tint color.', render: function() { return ( <View> <View style={styles.horizontal}> <Image source={require('image!uie_thumb_normal')} style={[styles.icon, {borderRadius: 5, tintColor: '#5ac8fa' }]} /> <Image source={require('image!uie_thumb_normal')} style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#4cd964' }]} /> <Image source={require('image!uie_thumb_normal')} style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#ff2d55' }]} /> <Image source={require('image!uie_thumb_normal')} style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#8e8e93' }]} /> </View> <Text style={styles.sectionText}> It also works with downloaded images: </Text> <View style={styles.horizontal}> <Image source={smallImage} style={[styles.base, {borderRadius: 5, tintColor: '#5ac8fa' }]} /> <Image source={smallImage} style={[styles.base, styles.leftMargin, {borderRadius: 5, tintColor: '#4cd964' }]} /> <Image source={smallImage} style={[styles.base, styles.leftMargin, {borderRadius: 5, tintColor: '#ff2d55' }]} /> <Image source={smallImage} style={[styles.base, styles.leftMargin, {borderRadius: 5, tintColor: '#8e8e93' }]} /> </View> </View> ); }, }, { title: 'Resize Mode', description: 'The `resizeMode` style prop controls how the image is ' + 'rendered within the frame.', render: function() { return ( <View style={styles.horizontal}> <View> <Text style={[styles.resizeModeText]}> Contain </Text> <Image style={styles.resizeMode} resizeMode={Image.resizeMode.contain} source={fullImage} /> </View> <View style={styles.leftMargin}> <Text style={[styles.resizeModeText]}> Cover </Text> <Image style={styles.resizeMode} resizeMode={Image.resizeMode.cover} source={fullImage} /> </View> <View style={styles.leftMargin}> <Text style={[styles.resizeModeText]}> Stretch </Text> <Image style={styles.resizeMode} resizeMode={Image.resizeMode.stretch} source={fullImage} /> </View> </View> ); }, }, { title: 'Animated GIF', render: function() { return ( <Image style={styles.gif} source={{uri: 'http://38.media.tumblr.com/9e9bd08c6e2d10561dd1fb4197df4c4e/tumblr_mfqekpMktw1rn90umo1_500.gif'}} /> ); }, platform: 'ios', }, { title: 'Cap Insets', description: 'When the image is resized, the corners of the size specified ' + 'by capInsets will stay a fixed size, but the center content and ' + 'borders of the image will be stretched. This is useful for creating ' + 'resizable rounded buttons, shadows, and other resizable assets.', render: function() { return <ImageCapInsetsExample />; }, platform: 'ios', }, ]; var fullImage = {uri: 'http://facebook.github.io/react/img/logo_og.png'}; var smallImage = {uri: 'http://facebook.github.io/react/img/logo_small_2x.png'}; var styles = StyleSheet.create({ base: { width: 38, height: 38, }, progress: { flex: 1, alignItems: 'center', flexDirection: 'row', width: 100 }, leftMargin: { marginLeft: 10, }, background: { backgroundColor: '#222222' }, sectionText: { marginVertical: 6, }, nestedText: { marginLeft: 12, marginTop: 20, backgroundColor: 'transparent', color: 'white' }, resizeMode: { width: 90, height: 60, borderWidth: 0.5, borderColor: 'black' }, resizeModeText: { fontSize: 11, marginBottom: 3, }, icon: { width: 15, height: 15, }, horizontal: { flexDirection: 'row', }, gif: { flex: 1, height: 200, }, });
更多建議: