• React-native初体验(安卓篇)


    本篇文章主要包括两方面,如何从0开始把RN(react-native)项目整合进入现有Android项目,以及我们做的第一个RN的上线项目遇到的一些坑。

    初次做RN项目,我们选择做了一个逻辑相对简单的转转app内部的帮助中心项目。整个项目有4个页面用的RN,其他页面走的是native提供的统跳协议,跳转到对应的native页面或者是H5页面。

    整合RN到android项目中

    react-native cli提供的init指令,可以帮助我们创建一个RN的工程,但是很多场景下RN都是移植进入原生android或者iOS中。例如应该如何实现,在Android页面,点击一个按钮进入RN页面呢?

    下面是具体的实现过程。

    1、新建一个Android项目

    注意Minimum SDK选择API23以上,一路next后finish。

    2、添加JS

    打开studio的Terminal窗口,输入如下命令:

    npm init
    会让你输入一些初始化package.json 的配置信息,例如:

    按照提示输入就行了。
    这一步完成之后,在项目的根目录下就会生成package.json这个文件,下一步输入:

    npm install react@16.0.0-alpha.6 - -save
    npm install react-native@^0.44.0 - -save

    注意,一定优先安装react哦

    大约一两分钟的样子(如果卡到这里了,看看安装时是不是忘了配置镜像),完成之后你的根目录下会多了一个node_modules的文件夹,里面存放了下载好的React 和React Native。这里有童鞋可能会质疑为什么不把react和react-native的依赖直接写入package.json中,然后直接npm install,如果这么做的化,npm run start启动的时候会报如下的错误:

    接下来把如下命令粘贴到package.json 文件下 scripts 标签中

    “start”: “node node_modules/react-native/local-cli/cli.js start”

    下一步,在根目录下创建index.android.js文件并把如下代码粘贴到其中:

    代码很简单,居中显示一个HelloWorld。

    3、项目配置(Android)

    用android studio打开工程,修改android根目录下Gradle Scripts的build.gradle(Module:app)文件添加如下内容,注意下面appcompat-v7版本为25.2.0,而且我把dependencies中test相关的依赖移除掉了,避免不必要的bug。

    在build.gradle(Project:***)中添加依赖

    继续下一步,在AndroidManifest.xml中添加网络访问权限

    4、创建Activity

    以下几步不要安装官网的去做,官网的步骤太麻烦,而且很久没有更新了。

    1.新建一个Activity,让其继承ReactActivity,并重写getMainComponentName(),返回我们在index.android.js中注册的HelloWorld这个组件。

    别忘了把这个activity加入app/manifests/AndroidManifest.xml文件中

    2.自定义一个Application,继承ReactApplication ,编写以下代码:

    记得在AndroidManifest.xml中引用

    android:name=”.App”

    3.在目录res/layout中增加activity_main.xml文件,内容如下:

    在MainActivity中通过按钮启动我们的ReactNativeActivity

    4.app/src/main下新建assets文件夹

    运行如下命令

    react-native start

    然后直接在android studio工程中,点击上方工具栏的“run”按钮,应该就可以了。
    如果卡在了这一步:

    没关系,用资源管理器打开你工程的根目录,在此目录下重新运行一个命令行并在其中输入如下命令

    react-native bundle - -platform android - -dev false - -entry-file index.android.js - -bundle-output app/src/main/assets/index.android.bundle - -assets-dest app/src/main/res/

    完成之后assets目录下会生成以下两个文件

    确认一下react native service处于运行状态,然后正常运行你的APP,点击start,如果出现

    恭喜你!你已经成功入坑,但是,实际项目中并不是这么简单!


    项目实战踩坑

     

    1.技术栈

    es6 + redux + react-redux + redux-thunk + react-navigation

    2.项目心得

    这个项目踩坑最多的地方还是在react-navigation的使用上:

    1、同一页面参数不同,多次回退始终进入同一个页面:
    比如详情页页面a/cateId/xy,当传入不同cateId参数“cd”跳转到同一详情页a/cateId/cd的时候,页面是正常改变的,但是回退的时候,第一次是回到a/cateId/cd,再次回退还是回到a/cateId/cd。不会触发页面render。
    stackNavigator导航管理的页面,在切换的时候,不是按照堆栈的push,pop形式,而是通过移动指针到对应的页面,同时标记此页面为激活状态。

    解决办法是通过componentWillReceiveProps,shouldComponentUpdate以及componentDidUpdate,当nextProps中的params.cateId和当前的params.cateId不同的时候,触发页面的render。

    2、实现手势swipe向右滑动后退功能:
    官方文档介绍,react-navigation在根组件的navigationOptions设置中添加gesturesEnabled: true,就可以实现滑动切换切换页面的需求,但是在真机上测试不生效。
    通过读源码了解到,react-navigation内部是通过引入RN的PanResponder手势识别系统来实现滑动的机制,只有在onMoveShouldSetPanResponder返回true的时候,才能执行接下来的手势动作。具体执行方法如下:

    因为上述代码中的 GESTURE_RESPONSE_DISTANCE_HORIZONTAL 过小,导致始终return false,把这个值从20改到60就可以了。

    3、实现页面跳转动画效果

    StackNavigator(RouteConfigs, StackNavigatorConfig);

    在第二个参数StackNavigatorConfig的配置中,可以传入mode: ‘card’,这个参数会在native端获取默认的滑动效果,iOS端默认的是左右切换的效果,但是android端默认的是上下切换效果。为了实现统一的过场效果。
    幸好react-navigation提供了一个transitionConfig接口,可以实现定制化滑屏效果。不知道该如何定制么?没有关系,源码中已经在iOS端帮我们实现,稍微修改一下代码就可以了。

    FlatList问题:

    1.ListHeaderComponent,ListFooterComponent
    当FlatList有并列的组件的时候,会出现,其他并列的组件位置是固定的(类似于css中的position fixed),页面只有FlatList区域是可以滚动的,为了实现这个页面整体是可以滚动的,需要把FlatList上面的组件加入FlatList的ListHeaderComponent属性中,同时把其下面的组件加入到ListFooterComponent中。

    2.通过利用getItemLayout,把高度提前设定好,可以较少一次RN计算高度的render。

     

    图片问题:

    1.RN中的图片有两种来源:native内部图片,cdn的图片。
    native内部图片,直接可以通过require图片名字取到,一定不要加.png等后缀。
    例如:

    当然我们可以通过在打包的时候把通过相对路径引入的内部图片,

    例如:

    通过配置–asset-dest打包进入native原生目录res中,这时候要注意,打出来的RN的bundle,只有放入android的assets文件夹下才能根据相对路径取到这些存放在res目录中的图片。

    cdn的图片,只有指定图片的宽高才能够显示出来。

    与native交互的处理

    1. NativeModules:native暴露出来的模块,可以通过NativeModules对象取到。

    2. 有些场景需要native直接传递某些参数到RN端,iOS可以通过调用initWithBundleURL,在initialProperties参数传参,android通过getLaunchOptions把参数写入返回的bundle中。在RN工程的根文件(例如app.js),通过this.props.key(key是属性名字)直接取到。

     如果你喜欢我们的文章,关注我们的公众号和我们互动吧。

    我们是转转FE团队,欢迎大家关注公众号 大转转FE 。更多的了解我们。官网 http://zzfed.com
  • 相关阅读:
    使用Fiddle修改请求数据
    Fiddle抓包应用概述
    s = -1 #作用域之外的数字是不会改的
    python list.reverse() 方法 不可以 ss = li.reverse() ,这个列表翻转方法没有返回值, ss=None
    python 两个tuple元组之间连接判断是否有一个为空, and 和 & ,只能用and 不能用&
    http 协议最大url是不限制的,但实际上不会很长,有服务器的限制
    这个居然也可以python >>>geturl()["a"]
    python的字典可以这样子 print(dic["ab"+cd]) 震惊!!!
    mysql 远程 死活连不上 阿里云搞得个什么鬼
    txt默认的是个什么格式,anex,什么的,另存为utf-8或者unicode中文就不乱了
  • 原文地址:https://www.cnblogs.com/zhuanzhuanfe/p/7213844.html
Copyright © 2020-2023  润新知