react-native中的圖片


靜態圖片資源
React Native 提供了一個統一的方式來管理 iOS 和 Android 應用中的圖片。要往 App 中添加一個靜態圖片,
只需把圖片文件放在代碼文件夾中某處,然后像下面這樣去引用它:

<Image source={require('./my-icon.png')} />

為了使新的圖片資源機制正常工作,require 中的圖片名字必須是一個靜態字符串
(不能使用變量!因為 require 是在編譯時期執行,而非運行時期執行!)。

// 錯誤
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} />;

請注意:通過這種方式引用的圖片資源包含圖片的尺寸(寬度,高度)信息,如果你需要動態縮放圖片(例如,通過 flex),
你可能必須手動在 style 屬性設置{ width: null, height: null }。
靜態的非圖片資源
上面描述的require語法也可以用來靜態地加載你項目中的聲音、視頻或者文檔文件。大多數常見文件類型都支持,
包括.mp3, .wav, .mp4, .mov, .htm 和 .pdf等(完整列表請看 packager defaults)。

你也可以創建自己的配置文件來支持其他類型的文件。具體的配置可以參考packager config file。

需要注意的是視頻必須指定尺寸而不能使用flex樣式,因為我們目前還不能從非圖片資源中獲取到尺寸信息。
對於直接鏈接到 Xcode 或者 Android 資源文件夾的視頻,則不會有這個限制。
使用混合 App 的圖片資源
如果你在編寫一個混合 App(一部分 UI 使用 React Native,而另一部分使用平台原生代碼),也可以使用已經打包到 App 中的圖片資源(以拖拽的方式放置在 Xcode 的 asset 類目中,或是放置在 Android 的 drawable 目錄里)。注意此時只使用文件名,不帶路徑也不帶后綴:

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

對於放置在 Android 的 assets 目錄中的圖片,還可以使用asset:/ 前綴來引用:

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

注意:這些做法並沒有任何安全檢查。你需要自己確保圖片在應用中確實存在,而且還需要指定尺寸。
網絡圖片
很多要在 App 中顯示的圖片並不能在編譯的時候獲得,又或者有時候需要動態載入來減少打包后的二進制文件的大小。
這些時候,與靜態資源不同的是,你需要手動指定圖片的尺寸。同時我們強烈建議你使用 https 以滿足 iOS App Transport Security
的要求。

// 正確
<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}}
       style={{width: 400, height: 400}} />

// 錯誤
<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}} />

網絡圖片的請求參數
你可以在 Image 組件的 source 屬性中指定一些請求參數,如下面的示例:

<Image
  source={{
    uri: 'https://facebook.github.io/react/logo-og.png',
    method: 'POST',
    headers: {
      Pragma: 'no-cache',
    },
    body: 'Your Body goes here',
  }}
  style={{width: 400, height: 400}}
/>

Uri 數據圖片
有時候你可能拿到的是圖片的 base64 數據,此時可以使用'data:'格式來顯示圖片。請注意,你需要手動指定圖片的尺寸。

建議僅對非常小的圖片使用 base64 數據,比如一些小圖標。

// 請記得指定寬高!
<Image
  style={{
    width: 51,
    height: 51,
    resizeMode: 'contain',
  }}
  source={{
    uri:
      'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg==',
  }}
/>

緩存控制(僅 iOS)
在某些情況下你可能僅僅想展示一張已經在本地緩存的圖片,例如一個低分辨率的占位符,直到高分辨率的圖片可用。又或者你無所謂圖片是否過時,而且也不在乎顯示過時的圖片,節省帶寬相對更重要。緩存資源屬性提供給了你控制網絡層與緩存交互的方式。

default: 使用原生平台默認策略。
reload: URL 的數據將從原始地址加載。不使用現有的緩存數據。
force-cache: 現有的緩存數據將用於滿足請求,忽略其期限或到期日。如果緩存中沒有對應請求的數據,則從原始地址加載。
only-if-cached: 現有的緩存數據將用於滿足請求,忽略其期限或到期日。如果緩存中沒有對應請求的數據,則不嘗試從原始地址加載,並且認為請求是失敗的。

<Image
  source={{
    uri: 'https://facebook.github.io/react/logo-og.png',
    cache: 'only-if-cached',
  }}
  style={{width: 400, height: 400}}
/>

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

在React Native中我們有意避免了這一行為。如此一來開發者就需要做更多工作來提前知曉遠程圖片的尺寸(或寬高比),但我們相信這樣可以帶來更好的用戶體驗。然而,讀取本地靜態圖片(使用require('./my-icon.png')語法)則無需指定尺寸,因為它們的尺寸在加載時就可以立刻知道。

比如這樣一個引用require('./my-icon.png')的實際輸出結果可能是:

{"__packager_asset":true,"uri":"my-icon.png","width":591,"height":573}

資源屬性是一個對象(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 中的背景圖(background-image)。要實現這一用例,只需使用 組件(其 props 與 完全相同),然后把需要背景圖的子組件嵌入其中即可。

也可能你並不需要使用 ,因為它的實現其實非常簡單,實質就是對圖片使用了絕對定位。你可以閱讀其文檔然后思考你是否有更好更簡單的布局方案。

return (
  <ImageBackground source={...} style={{width: '100%', height: '100%'}}>
    <Text>Inside</Text>
  </ImageBackground>
);

注意你必須指定寬高樣式。

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

borderTopLeftRadius
borderTopRightRadius
borderBottomLeftRadius
borderBottomRightRadius

在主線程外解碼圖片
圖片解碼有可能會需要超過一幀的時間。在 web 上這是頁面掉幀的一大因素,因為解碼是在主線程中完成的。然而在 React Native 中,
圖片解碼則是在另一線程中完成的。在實際開發中,一般對圖片還沒下載完成時的場景都做了處理(添加 loading 等),
而圖片解碼時顯示的占位符只占用幾幀時間,並不需要你改動代碼去額外處理。
相關相冊的那個demo明日解決


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM