使用 React Native 構建 Facebook Paper 相似的 UI

我模仿 Facebook 的 Paper 應用構建了一個開閉卡片的輪播效果做爲技術演示.它使用了 React Native 及其動畫庫.前端

當人們聽到 React Native 後第一反應會以爲它運行緩慢.這是由於通常人會去這樣解釋 React Native: "它容許你經過 Javascript 構建你的應用程序",而人們會認爲瀏覽器中運行的 JavaScript 性能並不夠好.react

但事實是,它採用的所有都是原生界面元素.但你經過 React Native 構建界面時, 每次都會實例化 Android 和 iOS 的原生 UI.所以,相比於比較沉重的 DOM 結構它是至關請輕量的.git

下面一段介紹:我是如何着手構建相似 Facebook 的 Paper 應用的交互效果的. 咱們能夠放大和縮小輪播圖,在動畫進行的時候,咱們也能夠中止它.github

先來看看它是什麼樣子:web

Actual screenshots from the working demo.

Actual screenshots from the working demo.

上面的屏幕截圖,是從我所構建的 App 中截出來的. 左邊是當前縮小的卡片列表.您能夠滑動它們.您也能夠把它拉起來,讓它們變成全屏. 如今你能夠在全屏狀態下滑動卡片,一個接一個. 咱們來與下面 Facebook Paper應用的交互模型來進行比較.vim

The zoomed out carousel of cards at the bottom.

點這裏查看 Youtube 上的視頻react-native

咱們以實例化兩個狀態變量開始.一個用於存儲 pan 值,另外一個存儲動畫進度:從0到1.這一進展變量是基於 pan 值進行插值.瀏覽器

let pan = new Animated.ValueXY();
this.state = {
  pan: pan,
  dockAnimation: pan.y.interpolate({
    inputRange: [-300, 0],
    outputRange: [0, 1],
  })
}

如今,咱們須要建立一個 panResponder. 這是一個複雜的手勢操控的概念,它判斷何時應該激活手勢以及們完成事件的各類方法.在咱們的例子中,咱們要在手勢正在進行和結束對它進行跟蹤.微信

this._panResponder = PanResponder.create({
  onStartShouldSetPanResponder: (evt, gestureState) => true,
  onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
  onMoveShouldSetPanResponder: (evt, gestureState) => true,
  onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
  onPanResponderGrant: () => {},
  onPanResponderMove: Animated.event([null, {dx: this.state.pan.x, dy: this.state.pan.y}]),
  onPanResponderRelease: (evt, gestureState) => {
    // dragging stopped, animate the item to the correct position
  }
})

在實際代碼中能夠看到看到 onPanResponderRelease 塊的所有實現.它作的很簡單:決定用戶是否已經拖遠遠,並切換 state 的值.若是是,繪製這個動畫.ide

transform: [{
  scale: this.state.dockAnimation.interpolate({
    inputRange: [0, 1],
    outputRange: [1, 0.5],
  })
}

多種變換被以 ListView 的 style 的方式應用. 我已經用 scale 變換做爲例子展現了,再一次,咱們使用插值來控制動畫.

<AnimatedListView
  style={this.getListViewStyle()}
  {...this._panResponder.panHandlers}
/>

最後,styles 和 panResponder 的 panResponder 都被綁定到了 ListView. 須要注意的是在咱們建立了一個一個組合式的 ListView: AnimatedListView,這樣的動畫庫能夠從樣式對象解析出動畫的值.

這就是咱們須要爲動畫作的全部事情!剩下的就是使用 Flex 佈局來構建那些漂亮的卡片.Jason Brown 寫了一本有關React Native動畫庫的好書:http://browniefed.com/react-n...

我在 Github 上共享了全部的代碼,你能夠自由修改它!

paramaggarwal/rn-paper-interface

<iframe src="https://player.vimeo.com/vide... width="640" height="1137" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>

目前,我只在iOS上運行過.可是你能夠嘗試在 Android 上運行,並在 github 上打開一個 PR. 我沒有用過任何的 iOS 特定的 API, 因此理論上,它應該在 Android 上工做.

做者信息
原文做者:Param Aggarwal
原文連接:http://t.cn/RtnSJwA
翻譯自力譜宿雲 LeapCloud旗下MaxLeap團隊_UX成員:Jason
中文首發地址:https://blog.maxleap.cn/archi...
譯者簡介:MaxLeap UX 組負責人,負責前端開發,客戶端/部分服務端 SDK 開發及開發者用戶體驗優化相關工做. 持續關注新技術,熱愛產品, 熱衷全棧/全端開發. 曾供職於搜狐搜狐武漢研究院,後投身 MaxLeap致力於爲開發者提供快速高效的開發體驗.


相關文章
ReactJS 開發過程當中的一些使用心得
在 React Web 和 原生 App 中共享代碼
React Native 一週年回顧
React.js 最佳實踐(2016)

做者往期做品
在 React Web 和 原生 App 中共享代碼
React.js 最佳實踐(2016)


活動預告

clipboard.png

報名連接:http://t.cn/Rt9ooRw


歡迎關注微信公衆號:MaxLeap_yidongyanfa

相關文章
相關標籤/搜索