天天看点

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,如需转载请自行联系原作者

继续阅读