您的位置:首页 > Web前端 > React

《React-Native系列》38、 ReactNative混合组件封装

2016-12-19 09:12 721 查看
在我们做ReactNative项目的过程中,我们会发现由ReactNative提供给我们的组件或API往往满足不了我们的需求,常常需要我们自己去封装Native组件。

今天我们介绍下如果封装一个简单的ReactNative组件,Native代码采用Android

需求:实现一个组件、实现类似Android的Toast功能。

1、创建一个RN project

[javascript] view
plain copy

 





react-native init HybridDemo  

如下:

[html] view
plain copy

 





$ react-native init HybridDemo  

This will walk you through creating a new React Native project in /Users/birenjie/RN/projects/HybridDemo  

Installing react-native package from npm...  

Setting up new React Native app in /Users/birenjie/RN/projects/HybridDemo  

HybridDemo@0.0.1 /Users/birenjie/RN/projects/HybridDemo  

└── react@15.3.2   

  

To run your app on iOS:  

   cd /Users/birenjie/RN/projects/HybridDemo  

   react-native run-ios  

   - or -  

   Open /Users/birenjie/RN/projects/HybridDemo/ios/HybridDemo.xcodeproj in Xcode  

   Hit the Run button  

To run your app on Android:  

   Have an Android emulator running (quickest way to get started), or a device connected  

   cd /Users/birenjie/RN/projects/HybridDemo  

   react-native run-android  

2、使用Android Studio打开新建的项目HybridDemo,新建一个空Library

如何新建一个Android的空Library,参考:Android Studio中为项目新建及添加Library

在这里我新建了一个Libray  : rn-toast-android

3、修改rn-toast-android下的build.gradle, 在dependencies中添加compile 'com.facebook.React:react-native:0.20.+'

如下:

4、在Library中新建AndroidToastModule.Java和AndroidToastPackage.java

AndroidToastModule.java代码如下:

[java] view
plain copy

 





package com.example.rn_toast_android;  

  

import android.widget.Toast;  

  

import com.facebook.react.bridge.ReactApplicationContext;  

import com.facebook.react.bridge.ReactContextBaseJavaModule;  

import com.facebook.react.bridge.ReactMethod;  

import com.facebook.react.common.MapBuilder;  

  

import java.util.Map;  

  

/** 

 * Created by birenjie on 16/10/11. 

 */  

public class AndroidToastModule extends ReactContextBaseJavaModule {  

  

    private static final String DURATION_SHORT_KEY = "SHORT";  

    private static final String DURATION_LONG_KEY = "LONG";  

  

    public AndroidToastModule(ReactApplicationContext reactContext) {  

        super(reactContext);  

    }  

  

  

    @Override  

    public String getName() {  

        return "ToastForAndroid";  

    }  

  

    @Override  

    public Map<String, Object> getConstants() {  

        final Map<String, Object> constants = MapBuilder.newHashMap();  

        constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);  

        constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);  

        return constants;  

    }  

  

    @ReactMethod  

    public void show(String message, int duration) {  

        Toast.makeText(getReactApplicationContext(), message, duration).show();  

    }  

}  

AndroidToastPackage.java代码如下:

[java] view
plain copy

 





package com.example.rn_toast_android;  

  

import com.example.rn_toast_android.AndroidToastModule;  

import com.facebook.react.ReactPackage;  

import com.facebook.react.bridge.JavaScriptModule;  

import com.facebook.react.bridge.NativeModule;  

import com.facebook.react.bridge.ReactApplicationContext;  

import com.facebook.react.uimanager.ViewManager;  

  

import java.util.Arrays;  

import java.util.Collections;  

import java.util.List;  

  

/** 

 * Created by birenjie on 16/10/11. 

 */  

public class AndroidToastPackage implements ReactPackage {  

  

    @Override  

    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {  

        return Arrays.<NativeModule>asList(new AndroidToastModule(reactContext));  

    }  

  

    //一般情况createJSModules()的返回值都是空集合。  

    @Override  

    public List<Class<? extends JavaScriptModule>> createJSModules() {  

        return Collections.emptyList();  

    }  

  

    //如果是BaseViewManager或其子类,那么createViewManagers()中返回的就是加入了BaseViewManager的集合  

    @Override  

    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {  

        return Collections.emptyList();  

    }  

}  

5、生成package.json

在....android/rn-toast-android/目录下 执行npm init 

会出现一系列的提示,按照提示完成,最后可以生成package.json 文件

6、测试我们编写的组件

在我们init的项目的根目录(index.android.js)同级目录,新建ToastForAndroid.js

ToastForAndroid.js源码如下:

[javascript] view
plain copy

 





'use strict';  

  

import React, { Component } from 'react';  

import {  

  NativeModules,  

} from 'react-native';  

  

const {ToastForAndroid}  = NativeModules;  

  

  

var ToastForAndroidDemo = {  

  

  SHORT: ToastForAndroid.SHORT,  

  LONG: ToastForAndroid.LONG,  

  

  show: function (  

    message: string,  

    duration: number  

  ): void {  

    ToastForAndroid.show(message, duration);  

  },  

  

};  

  

module.exports = ToastForAndroidDemo;  

修改index.android.js,如下:

[javascript] view
plain copy

 





/** 

 * Sample React Native App 

 * https://github.com/facebook/react-native 

 * @flow 

 */  

  

import React, { Component } from 'react';  

import {  

  AppRegistry,  

  StyleSheet,  

  Text,  

  View,  

  Dimensions,  

  TouchableHighlight,  

} from 'react-native';  

  

  

import ToastForAndroid from './ToastForAndroid';  

  

var deviceWidth = Dimensions.get('window').width;  

var deviceHeight = Dimensions.get('window').height;  

  

class HybridDemo extends Component {  

  render() {  

    return (  

      <TouchableHighlight  onPress= {()=>ToastForAndroid.show('I am clicked ', ToastForAndroid.LONG)}>  

        <Text style={{width:deviceWidth,height:50,backgroundColor:'red',textAlign:'center',textAlignVertical:'center'}}>点击调用Native方法</Text>  

      </TouchableHighlight>  

    );  

  }  

}  

  

AppRegistry.registerComponent('HybridDemo', () => HybridDemo);  

我们需要修改的MainApplication.java,将AndroidToastPackage加入到ReactPackage

[java] view
plain copy

 





@Override  

protected List<ReactPackage> getPackages() {  

  return Arrays.<ReactPackage>asList(  

      new MainReactPackage(),new AndroidToastPackage()  

  );  

}  

好,一切准备就绪,我们启动React packager Server。

运行效果如下:

至此,我们自己封装的Android  Toast组件就完成了。

如果我们有npm的镜像服务器,我们还可以把我们的组件发布上去。

在..../android/rn-toast-android/ 目录下执行

$ npm adduser   //增加npm用户

$ npm publish  //上传组件到npm上

这样我们就可以像使用第三方组件一样,使用自己发布的ReactNative混合组件了。

参考:http://blog.csdn.NET/zzyyppqq/article/details/50349905
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: