关于RN工作使用中的见解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuxingyuzaixian/article/details/80523643

一、选择RN的优势与劣势

优势:

1,提升产品迭代速度,需求/交互评审不再需要与多端开发同时沟通,避免多端开发理解不一致,而且呢,某一个功能模块开发测试只需要交付一个人负责,测试也是;

2,提升开发效率,统一使用flex布局,使用最新语法(比如现在的ES6语法),特别是拓展操作符,灵活方便;
3,提供团队成员个人发展的更多选择,促进大前端成员技术交流,促进全栈工程师的形成;
4,提供热更新HotFix,当然这个在android原生端也比较容易实现;

劣势:

1,对跨平台并不是100%兼容的,部分功能表现在android与ios上面不一致,很难通过UI与产品的走查,需要另外用原生支持。而且对动画比较丰富和页面支持也比较困难,耗时长效果差,对;

2,开发时需要开两个IDE,对电脑性能要求高,环境切换用同时切换RN与原生的环境,较为繁琐。
 

二、RN与原生交互

2.1,原生跳转RN:

扫描二维码关注公众号,回复: 5090995 查看本文章
public Bundle getLaunchOptions() {
        Bundle bundle = new Bundle();
        bundle.putString("params", new Gson().toJson(activityParams));
        return bundle;
    }

2.2,RN处理接收原生传递的参数:

let params = this.(props.navigation.state.)params.pageParams.shopName

2.3,RN之间页面的跳转:

this.navigate(RouterPaths.SerachCarBrand, {
                finish: (model) => this.finishChooseModel(model)
});

回调方法其传过来的方法:

this.params.finish(item)

2.4,RN接收RN传递的参数:

this.shopName = this.params && this.params.pageParams

2.5,RN页面返回:

navigateBack = (routerKey = '') => {
        if (StringUtils.isNoEmpty(routerKey)) {
            const backAction = NavigationActions.back({key: routerKey,})
            this.props.navigation.dispatch(backAction);
        } else {
            this.props.navigation.goBack()
        }
}

2.6,RN调用原生的方法

NativeModules.commModule.getNativeStore(constants.isEnglish, value => {
            this.setState({isEnglish: (value == 1) || (value == '')});
        })

2.7,原生提供方法

public class CommModule extends ReactContextBaseJavaModule {
    @ReactMethod
    public void refleshUserInformation() {
        EventBus.getDefault().post("EVENT_REFLESH_USER_DATA");//登录刷新用户头像等信息
    }
}

2.8,原生调用RN的方法
发送事件(其中EVENT_NAME与msg都为String类型)

mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(EVENT_NAME, msg);

注册事件

DeviceEventEmitter.addListener('Event',(str)=>{
    
})

2.9,对于RN多级回退

this.navigateBack(this.params.key)

同时需要在中间页面维护页面标志key值

(key:this.key)


RN与原生交互参考https://blog.csdn.net/asddavid/article/details/53338616

三、RN的flex布局方式:

flex:1    ->设置占据剩余全部布局
flexDiretion:’row’ ->设置水平布局,默认垂直布局
row:主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column(默认值):主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。
justify-content: ‘center ’ ->定义了项目在主轴上的对齐方式。
flex-start(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两端对齐,项目之间的间隔都相等。
space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
alignItems:'center' ->定义项目在交叉轴上如何对齐
  配合justify-content:‘center’可以实现gravity:”center”的效果
flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐。
center:交叉轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
align-content:‘center’ ->定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用
      使用略少
flex-start:与交叉轴的起点对齐。
flex-end:与交叉轴的终点对齐。
center:与交叉轴的中点对齐。
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴。
Flex布局相关参考http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

四、RN控件使用

<Image source={search_img} style={{marginLeft: 8, width: 17, height: 17,marginTop:2}}/>
<Text style={{textColor:color.black_more_light,marginLeft:constant.dp10}}>
{strings.searchCategory}
</Text>
<FavoritesItam
strGoodsImageUri={item.strGoodsImageUri}
strGoodsContent={item.strGoodsContent}
partNum={item.partNum}
clickItemJump={()=>this.clickItemJump(item,index)}
clickItemLike={()=>this.clickItemMore(item,index)}
strShopName={item.strShopName}/>

声明

const FavoritesItem = props => {
    
const {
strGoodsImageUri,
        ...attributes
    } = props
    
return (
        
<View></View>
    
);

};

export default FavoritesItem;

RN控件相关参考官网https://facebook.github.io/react-native/docs/next/listview.html
 

五、ES6语法特性

数据与对象的解构:

let { bar, foo } = { foo: "aaa", bar: "bbb" };

函数的扩展:

function foo(x = 5, y = 6) {
  console.log(x, y);
}

标签模板:

let a = 5;
let b = 10;
let s=`Hello ${ a + b } world ${ a * b }`
console.log(s)

Es6语法特性参考http://es6.ruanyifeng.com/#docs/string


六、react native屏幕适配

/**
 * 屏幕适配工具类
 * ui设计基准,iphone 6
 * width:750
 * height:1334
 * 灵活使用以下方法进行适配
 * 思想主要是以1,react-native提供的dp、2,flex权重进行适配为主,以3,getAutolayoutWidth()、4,自行计算宽度为辅。一般情况不按高度适配:
 * 
 * 1,布局适配方法
 *      1.1,使用react-native提供的dp进行适配
 *      1.2,使用权重flex=1进行比例适配
 *      1.3,使用提供的getAutolayoutWidth()进行适配
 * 
 * 2,文字适配方法
 *      2.1,对于限定行数的Text
 *          使用numberOfLines={1}属性,多余部分会以省略号显示。
 *          也可以加入属性:ellipsizeMode,取值为:
 *              	head:从文本的开头进行截断,并在文本的开头添加省略号,例如:...xyz。
 *	                middle :从文本的中间进行截断,并在文本的中间添加省略号,例如:ab...yz。
 *	                tail:从文本的末尾进行截断,并在文本的末尾添加省略号,例如:abcd...。
 *	                clip :文本的末尾显示不下的内容会被截断,并且不添加省略号,clip只适用于iOS平台。
 *           如要显示具体详情可以咨询产品,加入文字详情弹窗
 *      2.2,对于不限行的Text,可以自动排到下一行,页面可以考虑用ScrollView包裹
 * 
 * 3,图片适配方法
 *      3.1,对于占据空间比较小的icon,一般不会产生适配问题
 *              3.1,1,进行正常的react-native的dp适配即可
 *      3.2,对于占据空间比较大的图片,对不同手机的显示效果区别较大
 *              3.2,1,使用工具类中提供的screenWidth自行计算百分比宽度
 *              3.2.2,使用提供的getAutolayoutWidth()进行适配
 */

import {
    Dimensions, 
    Platform, 
    PixelRatio
} from 'react-native';
// 设计稿宽度
const designPageScreenWidth=750;

// 设计稿高度
const designPageScreenHeight=1334;

const MAX_SCREENT = Math.max(Dimensions.get('window').width, Dimensions.get('window').height);
const MIN_SCREENT = Math.min(Dimensions.get('window').width, Dimensions.get('window').height);
const __ISIPHONEX__ = Platform.OS === 'ios' && (MIN_SCREENT === 375.0 && MAX_SCREENT === 812.0);

/**
 * 设计稿宽度px=>动态实际手机宽度dp
 * 有需要以宽度适配为主,注意这里是入参是px
 * 实测在react-native中iphone X,iphone 6的宽度dp都是375,android Nexus_5X_API_27的宽度dp为411.42857142857144
 */
function getAutolayoutWidth(width:number){
    return width/designPageScreenWidth*Dimensions.get('window').width;
}

/**
 * 设计稿高度px=>动态实际手机高度dp
 * 高度适配场景较少,慎用
 */
function getAutolayoutHeight(height:number){
    return height/designPageScreenHeight*Dimensions.get('window').height;
}

/**
 * 对外提供的方法
 */
export default{
    screenWidth: Dimensions.get('window').width,
    screenHeight: Dimensions.get('window').height,
    pixelRatio: PixelRatio.get(),
    onePixel: 1 / PixelRatio.get(),
    statusBarHeight: Platform.OS === 'ios' ? (__ISIPHONEX__ ? 44 : 20) : 20,// (Platform.OS === 'ios' ? 20 : 0),
    headerHeight: Platform.OS === 'ios' ? (__ISIPHONEX__ ? 88 : 64) : 48,
    tabBarHeight: Platform.OS === 'ios' ? (__ISIPHONEX__ ? 83 : 49) : 49,
    isIOS: Platform.OS === 'ios',
    isIOSSmall: Platform.OS === 'ios' && Dimensions.get('window').height === 568,// phoneSE,phone4,phone5,phone5s
    isIOSNomarl: Platform.OS === 'ios' && Dimensions.get('window').height === 667,// phone6,phone7,phone8
    isIOSP: Platform.OS === 'ios' && Dimensions.get('window').height === 736,//phone6p,phone7p,phone8p
    isIOSX: Platform.OS === 'ios' && Dimensions.get('window').height === 812,
    getAutolayoutWidth,
    getAutolayoutHeight,
}

猜你喜欢

转载自blog.csdn.net/liuxingyuzaixian/article/details/80523643