天天看點

React Native填坑之旅--Navigation篇

React Native的導航有兩種,一種是iOS和Android通用的叫做Navigator,一種是支援iOS的叫做NavigatorIOS。我們這裡隻讨論通用的Navigator。會了Navigator,NavigatorIOS也就不是什麼難事了。

本文所使用的是React Native 0.34。FB團隊更新的太快了,我會在後續出現大的改動的時候更新本文以及代碼。

Navigator在不同的Scene之間跳轉。

initialRoute對象

這是Navigator所必須的,用于指定第一個Scene。

renderScene方法,這個方法必須。用flow的文法來描述的話是這樣的<code>renderScene(router: any, navigator: Navigator)</code>。<code>renderScene</code>方法用來根據一個給定的route來繪制Scene。如:

push方法,<code>push(route: any)</code>。Navigator使用這個方法跳轉到一個新的Scene。

API就了解這麼多,下面看一個簡單的例子。資料都是寫死的。

這個例子的主要功能就是從一個Scene(元件)HomeController,跳轉到另外的一個元件PetListController。就是從一組使用者裡點選一個之後顯示這個使用者擁有的寵物清單。

代碼裡的User資料以及使用者的Pets資料都是寫死的。如果要學習網絡請求方面的内容可以參考<code>HomeController</code>裡的<code>fetchAction</code>方法,以及填坑系列的前篇Http篇。

HomeController,在這個元件裡顯示使用者清單。

文中儲備要代碼都已經略去。

你可以看到,資料源就是一個數組<code>['Micheal', 'Jack', 'Paul']</code>,裡面有三個人。資料最後顯示在<code>ListView</code>裡。

行渲染的時候,在行的裡面添加可以相應點選的<code>TouchableHighlight</code>,在使用者點選之後跳轉到<code>PetListController</code>中。

另外的一個<code>PetListController</code>裡隻是顯示某個使用者的寵物清單。

在這個元件裡顯示的就是寵物資料。展示方式也是用的<code>ListView</code>。

在本例中,導航開始的地方不在某個具體的Controller裡(元件),而是在index.ios.js,android的在index.android.js裡。這麼做并不好,以後重構代碼的時候會提升到同一個檔案中。

我們從Navigator繪制的地方開始導航的講解:

回顧一下最開始的API,<code>renderScene</code>方法是用來繪制每一個Scene(場景)。Sene的實質就是一個個的元件,這個元件會占滿一個螢幕。

元件的繪制需要有一些基本的資訊,這個資訊就是在<code>initialRoute</code>裡指定的。

這個<code>initialScene</code>是一個對象,内容有你自己定。

下面看看Scene的繪制方法<code>renderScene</code>:

這個方法每次都會傳回一個<code>ReactElement</code>執行個體,和<code>JSX</code>文法傳回的是一樣的,雖然JSX看起來是這樣的<code>&lt;HomeController /&gt;</code>。

這樣寫可能對于初學者來說有一點繞,那麼更加直覺一點的寫法是什麼樣呢?來看看:

這個寫法作用就是根據使用者目前要通路的Route的index值來繪制相應的元件來作為目前的Scene。

但是,如此寫法也略顯複雜。你在寫這個render方法的時候需要知道全部的導航路勁,即從一開始是哪個Scene,第二部導航到哪個Scene,第三部。。。以此類推。在Navigator路徑上有幾個Scene就需要寫幾個。是以使用第一種寫法,用<code>createElement</code>方法來,根據指定的元件執行個體來傳回作為Scene使用的元件。

上面的例子運作出來的時候有一個極大的問題,你不注意的話在PetListController沒法傳回到HomeController。

界面上并沒有傳回按鈕,但是RN居然把iOS的在最左側的手勢拖動傳回上一級的功能實作了。這個功能在Android的實作上也有。總之隐藏不見的這個功能在使用者體驗上會有很大的問題。

是以必須用到Navigator的<code>NavigationBar</code>。

NavigatorBar裡設定了三個元素,左右兩個按鈕和中間的Title。上面代碼中的按鈕無法響應使用者的點選操作。下面就看看如何添加這部分代碼:

理論上如的部分就看到這裡。我們看看我們的代碼是怎麼添加的:

在左側按鈕中,首先檢查目前Scene的index是多少。如果是大于0的就說明可以回退到上一級,否則不作處理。

另外,給Title也添加了響應點選的代碼。但是隻是一個效果,沒有添加<code>onPress</code>事件的處理代碼。

總結一下上面的内容。需要跳轉的HomeController和PetListController已經準備好了。導航用的Navigator也配置完成了,并且也包括NavigationBar。在繪制每一個Secne的時候,也給這些Scene傳入了props,裡面包含了Route對象和navigator對象。

有了上面的内容隻是可以在運作起來的時候顯示第一個Scene:HomeController。于是,在HomeController的ListView裡的Row繪制的時候添加了<code>TouchableHighLight</code>并在相應事件裡調用了Navigator的<code>push</code>方法跳轉到下一個Scene。

push方法裡傳入的對象就是Route類型(基本就是類型這個概念)。這個對象指明要跳轉的是哪個Scene,以及其他資訊。

pop方法在上面的NavigationBar裡的左側按鈕已經講到。

要完全的實作Navigation,需要用到Navigator和跳轉的Scene(元件)。而把他們串聯起來的是Route定義和作為props傳入每個Scene的navigator對象。

歡迎加群互相學習,共同進步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,轉載請注明出處!

本文轉自張昺華-sky部落格園部落格,原文連結:http://www.cnblogs.com/sunshine-anycall/p/5958012.html,如需轉載請自行聯系原作者

繼續閱讀