RN組件 - Image圖片

Image,通過這個組件可以展示各種各樣的圖片,而且在React Native中該組件可以通過多種方式加載圖片資源。


一、Image組件的基本用法

1.1 從當前項目中加載圖片

要往App中添加一個靜態圖片,只需把圖片文件放在代碼文件夾中某處,然後像下面這樣去引用它:
<Image source={require('./my-icon.png')} />  即:

            <View style={styles.container}>
                {/*從項目中加載圖片*/}
              <Text>從項目中加載圖片</Text>
              // 在imageStyle中指定寬高
              <Image source={require('./img/icon.png')} style={styles.imageStyle} />

     該圖片資源文件的查找和JS模塊相似,該會根據填寫的圖片路徑相對於當前的js文件路徑進行搜索。

     此外,React Naive的Packager會根據平臺選擇相應的文件,例如:my_icon.ios.png和my_icon.android.png兩個文件(命名方式android或者ios),會分別根據android或者ios平臺選擇相應的文件。

你還可以使用@2x,@3x這樣的文件名後綴,來爲不同的屏幕精度提供圖片。比如下面這樣的代碼結構:
.
├── button.js
└── img
    ├── [email protected]
    └── [email protected]
並且button.js裏有這樣的代碼:

<Image source={require('./img/check.png')} />
Packager會打包所有的圖片並且依據屏幕精度提供對應的資源。譬如說,iPhone 5s會使用[email protected],而Nexus 5上則會使用[email protected]。如果沒有圖片恰好滿足屏幕分辨率,則會自動選中最接近的一個圖片。
注意:如果你添加圖片的時候packager正在運行,可能需要重啓packager以便能正確引入新添加的圖片。

這樣會帶來如下的一些好處:

iOS和Android一致的文件系統。 圖片和JS代碼處在相同的文件夾,這樣組件就可以包含自己所用的圖片而不用單獨去設置。 不需要全局命名。你不用再擔心圖片名字的衝突問題了。 只有實際被用到(即被require)的圖片纔會被打包到你的app。 現在在開發期間,增加和修改圖片不需要重新編譯了,只要和修改js代碼一樣刷新你的模擬器就可以了。 與訪問網絡圖片相比,Packager可以得知圖片大小了,不需要在代碼裏再聲明一遍尺寸。現在通過npm來分發組件或庫可以包含圖片了。
另一種寫法:
// 錯誤
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />

// 正確
var icon = this.props.active ? require('./my-icon-active.png') : require('./my-icon-inactive.png');
<Image source={icon} />

1.2 加載使用APP中的圖片

<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />

{/*從資源包中加載圖片*/}
 <Text>2.從APP中加載圖片</Text>
 <Image source={{uri:'icon_a'}} style={styles.imageStyle} />

使用已經打包在APP中的圖片資源(例如:xcode asset文件夾以及Android drawable文件夾)

注意:這一做法並沒有任何安全檢查。你需要自己確保圖片在應用中確實存在,而且還需要指定尺寸。

爲什麼不在所有情況下都自動指定尺寸呢?
在瀏覽器中,如果你不給圖片指定尺寸,那麼瀏覽器會首先渲染一個0x0大小的元素佔位,然後下載圖片,在下載完成後再基於正確的尺寸來渲染圖片。這樣做的最大問題是UI會在圖片加載的過程中上下跳動,使得用戶體驗非常糟糕。

在React Native中我們有意避免了這一行爲。可以從已經打包好的應用資源文件中讀取圖片(使用require('image!x')語法)則無需指定尺寸,因爲它們的尺寸在加載時就可以立刻知道。
{/*從資源包中加載圖片--另一種方式*/}
<Text>4.從APP中加載圖片</Text>
<Image source={require('image!icon_a')} style={styles.imageStyle} />

比如這樣一個引用require('image!logo')的實際輸出結果可能是:
{"__packager_asset":true,"isStatic":true,"path":"/Users/react/HelloWorld/iOS/Images.xcassets/react.imageset/logo.png","uri":"logo","width":591,"height":573}

1.3 加載來自網絡的圖片

       客戶端的很多圖片資源基本上都是實時通過網絡進行獲取的,寫法和上面的加載本地資源圖片的方式不太一樣,這邊一定需要指定圖片的尺寸大小,實現如下:

{/*從網絡中加載圖片*/}
 <Text>3.從網絡中加載圖片</Text>
 <Image source={{uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'}}
        style={styles.imageStyle} />


1.4 設置圖片爲背景

    <Image source={{uri:'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg
'}} style={{flex:1,width:200, height:100, resizeMode: Image.resizeMode.stretch}}>

           <Text style={{marginTop: 60, backgroundColor: 'red'}}>下面是背景圖片</Text>

    </Image>


通過嵌套來實現背景圖片
開發者們常面對的一種需求就是類似web中的背景圖(background-image)。要實現這一用例,只需簡單地創建一個<Image>組件,然後把需要背景圖的子組件嵌入其中即可。

return (
  <Image source={...}>
    <Text>Inside</Text>
  </Image>
);
示例代碼: 

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Image
} from 'react-native';

/*********** 背景圖片示例****************/
export default class ImageDemoA extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Image
        style={styles.backgroundImage}
        source={{uri:'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'}}>
        <View style={styles.overlay}>
          <Text style={styles.overlayHeader}>水果水果</Text>
          <Text style={styles.overlaySubHeader}>有什麼呢</Text>
        </View>
        </Image>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    backgroundColor: '#F5FCFF',
    paddingTop:30
  },
  image:{
    width:100,
    height:140,
    margin:6
  },
  backgroundImage:{
    flex:1,
      //背景圖像的縮放類型: 包含(contain),拉伸(stretch)
    resizeMode:'cover'
  },
  overlay:{
     backgroundColor:'rgba(0,0,0,0.3)',
     alignItems:'center'
  },
    overlayHeader:{
    fontSize:33,
    fontFamily:'Helvetica Neue',
    fontWeight:'200',
    color:'#eae7ff',
     padding:10
    },
    overlaySubHeader:{
        fontSize:15,
        fontFamily:'Helvetica Neue',
        fontWeight:'200',
        color:'#eae7ff',
        padding:10,
        paddingTop:0
    }
});

AppRegistry.registerComponent('ImageDemoA', () => ImageDemoA);


二、Image組件的常見屬性

2.1 屬性方法

   onLayout(function)

   當Image佈局發生改變的,會進行調用該方法,調用的代碼爲:{nativeEvent: {layout: {x, y, width, height}}}.

   onLoad (function)

   當圖片加載成功之後,回調該方法

   onLoadEnd (function)

   當圖片加載失敗回調該方法,該不會管圖片加載成功還是失敗

   onLoadStart (fcuntion)

   當圖片開始加載的時候調用該方法

  resizeMode

   縮放比例,可選參數('cover', 'contain', 'stretch') 該當圖片的尺寸超過佈局的尺寸的時候,會根據設置Mode進行縮放或者裁剪圖片

    resizeMode這樣一個屬性,這個屬性的作用相當於OC中設置圖片的內容模式。

 Image.resizeMode.cover:圖片居中顯示,沒有被拉伸,超出部分被截斷;

 Image.resizeMode.contain:容器完全容納圖片,圖片等比例進拉伸;

 Image.resizeMode.stretch: 圖片被拉伸適應容器大小,有可能會發生變形。

  source{uri:string}

   進行標記圖片的引用,該參數可以爲一個網絡url地址或者一個本地的路徑


2.2 樣式風格屬性

  FlexBox  支持彈性盒子風格

  Transforms  支持屬性動畫

  backgroundColor 背景顏色

  borderColor     邊框顏色

  borderWidth 邊框寬度

  borderRadius  邊框圓角

  overflow 設置圖片尺寸超過容器可以設置顯示或者隱藏('visible','hidden')

  tintColor  顏色設置

  opacity 設置不透明度0.0(透明)-1.0(完全不透明)


iOS邊框圓角的注意事項
請注意下列邊框圓角樣式目前在iOS的圖片組件上還不支持:
borderTopLeftRadius
borderTopRightRadius
borderBottomLeftRadius
borderBottomRightRadius



最合適的相冊圖片
iOS會爲同一張圖片在相冊中保存多個不同尺寸的副本。爲了性能考慮,從這些副本中挑出最合適的尺寸顯得尤爲重要。對於一處200x200大小的縮略圖,顯然不應該選擇最高質量的3264x2448大小的圖片。如果恰好有匹配的尺寸,那麼React Native會自動爲你選好。如果沒有,則會選擇最接近的尺寸進行縮放,但也至少縮放到比所需尺寸大出50%,以使圖片看起來仍然足夠清晰。這一切過程都是自動完成的,所以你不用操心自己去完成這些繁瑣且易錯的代碼。


資源屬性是一個對象(object)
在React Native中,另一個值得一提的變動是我們把src屬性改爲了source屬性,而且並不接受字符串,正確的值是一個帶有uri屬性的對象。

<Image source={{uri: 'something.jpg'}} />
深層次的考慮是,這樣可以使我們在對象中添加一些元數據(metadata)。假設你在使用require('./my-icon.png'),那麼我們就會在其中添加真實文件路徑以及尺寸等信息(這只是舉個例子,未來的版本中require的具體行爲可能會變化)。此外這也是考慮了未來的擴展性,比如我們可能會加入精靈圖(sprites)的支持:在輸出{uri: ...}的基礎上,我們可以進一步輸出裁切信息{uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}},這樣理論上就可以在現有的代碼中無縫支持精靈圖的切分。
對於開發者來說,則可以在其中標註一些有用的屬性,例如圖片的尺寸,這樣可以使圖片自己去計算將要顯示的尺寸(而不必在樣式中寫死)。請在這一數據結構中自由發揮,存儲你可能需要的任何圖片相關的信息。


在主線程外解碼圖片
圖片解碼有可能會需要超過一幀的時間。在web上這是頁面掉幀的一大因素,因爲解碼是在主線程中完成的。然而在React Native中,圖片解碼則是在另一線程中完成的。在實際開發中,一般對圖片還沒下載完成時的場景都做了處理(添加loading等),而圖片解碼時顯示的佔位符只佔用幾幀時間,並不需要你改動代碼去額外處理。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章