在我们做ReactNative项目的过程中,我们会发现由ReactNative提供给我们的组件或API往往满足不了我们的需求,常常需要我们自己去封装Native组件。
  
  今天我们介绍下如果封装一个简单的ReactNative组件,Native代码采用Android。
  
  需求:实现一个组件、实现类似Android的Toast功能。
  
  1、创建一个RN project
  
  [javascript] view plain copy 在CODE上查看代码片派生到我的代码片
  
  react-native init HybridDemo
  
  如下:
  
  [html] view plain copy 在CODE上查看代码片派生到我的代码片
  
  $ 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/www.lxinyul.cc 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 在CODE上查看代码片派生到我的代码片
  
  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(www.hsl85.cn/ 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 在CODE上查看代码片派生到我的代码片
  
  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或其子类,那么createViewwww.zhenlyule.cn/ Managers()中返回的就是加入了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 在CODE上查看代码片派生到我的代码片
  
  '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, www.ycyc66.cn/ duration);
  
  },
  
  };
  
  module.exports = ToastForAndroidDemo;
  
  修改index.android.js,如下:
  
  [javascript] view plain copy 在CODE上查看代码片派生到我的代码片
  
  /**
  
  * 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 = www.zhenloyl88.cn 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 在CODE上查看代码片派生到我的代码片
  
  @Override
  
  protected List<ReactPackage> www.wx1677.com/ getPackages() {
  
  return Arrays.<ReactPackage>asList(
  
  new MainReactPackage(),new AndroidToastPackage()
  
  );
  
  }
  
  好,一切准备就绪,我们启动React packager Server。
  
  运行效果如下:
  
  至此,我们自己封装的Android Toast组件就完成了。
  
  如果我们有npm的镜像服务器,我们还可以把我们的组件发布上去。
  
  在..../android/rn-toast-androi www.yghrcp88.cn d/ 目录下执行
  
  $ npm adduser //增加npm用户
  
  $ npm publish //上传组件到npm上
  
  这样我们就可以像使用第三方组件一样,使用自己发布的ReactNative混合组件了。

《React-Native系列》38、 ReactNative混合组件封装的更多相关文章

  1. React Native 系列(九) -- Tab标签组件

    前言 本系列是基于React Native版本号0.44.3写的.很多的App都使用了Tab标签组件,例如QQ,微信等等,就是切换不同的选项,显示不同的内容.那么这篇文章将介绍RN中的Tab标签组件. ...

  2. 【REACT NATIVE 系列教程之十二】REACT NATIVE(JS/ES)与IOS(OBJECT-C)交互通信

    http://blog.csdn.net/xiaominghimi/article/details/51586492 一用到跨平台的引擎必然要有引擎与各平台原生进行交互通信的需要.那么Himi先讲解R ...

  3. React Native之本地文件系统访问组件react-native-fs的介绍与使用

    React Native之本地文件系统访问组件react-native-fs的介绍与使用 一,需求分析 1,需要将图片保存到本地相册: 2,需要创建文件,并对其进行读写 删除操作. 二,简单介绍 re ...

  4. React Native 系列(五) -- 组件间传值

    前言 本系列是基于React Native版本号0.44.3写的.任何一款 App 都有界面之间数据传递的这个步骤的,那么在RN中,组件间是怎么传值的呢?这篇文章将介绍到顺传.逆传已经通过通知传值. ...

  5. React Native系列(6) - 编译安卓私有React-Native代码

    为何要自己编译React Native安卓私有代码 我们在开发中遇到一个HTTP2的问题,React Native安卓客户端在和HTTP2支持的服务器通讯的过程中会有crash,见 React-Nat ...

  6. React Native 系列(二) -- React入门知识

    前言 本系列是基于React Native版本号0.44.3写的,最初学习React Native的时候,完全没有接触过React和JS,本文的目的是为了给那些JS和React小白提供一个快速入门,让 ...

  7. React Native 系列(二)

    前言 本系列是基于React Native版本号0.44.3写的,最初学习React Native的时候,完全没有接触过React和JS,本文的目的是为了给那些JS和React小白提供一个快速入门,让 ...

  8. React Native 系列(八) -- 导航

    前言 本系列是基于React Native版本号0.44.3写的.我们都知道,一个App不可能只有一个不变的界面,而是通过多个界面间的跳转来呈现不同的内容.那么这篇文章将介绍RN中的导航. 导航 什么 ...

  9. React Native 系列(三) -- 项目结构介绍

    前言 本系列是基于React Native版本号0.44.3写的,相信大家看了本系列前面两篇文章之后,对于React Native的代码应该能看懂一点点了吧.本篇文章将带着大家来认识一下React N ...

随机推荐

  1. ASP.NET【2】

    从上一节我们了解到ASP.NET是一种动态网页技术,在服务器端运行.Net代码,服务器端接收处理动态生成HTML代码,然后发送给浏览器,再由浏览器解析HTML代码将数据呈现给用户. 那么,下面我来介绍 ...

  2. Android——C语言、JNI与低层调用

    JNI java native interface c的基本数据类型 int:32位,能表示的数字是2的32次方个 最高位用来表示符号位,那么还剩下31位可以表示数值,所以能表示的数字就是2的31次方 ...

  3. PHP判断变量是否为长整形的方法

    PHP判断变量是否为长整形的方法,可用于判断QQ号等,避免了int溢出的问题 <?php /** * 判断变量是否为长整数(int与整数float) * @param mixed $var * ...

  4. docker学习资料整理(持续更新中..)

    docker最近可以说火得一踏糊涂,跟 51大神在交流技术的时候这个东西会多次被提到,当我们还玩vm+linux/freebsd的时候,人家已经上升到更高层次了,这就是差距,感觉好高大上的样子,技术之 ...

  5. PAT---1013. Battle Over Cities (25)

    这道题目的意思是:在战争时代,如果一个城市被敌人占领了,那么和该城市相连的道路都必须关闭,我们必须把剩下的城市(即不包括被敌人占领的城市)连接起来. 举个例子,我们有3个城市,C1,C2,C3,C1和 ...

  6. im消息丢失插件

    https://github.com/laughin/mocamsg mocamsg Moca message interceptor Openfire网络不好的情况下经常丢消息,一般情况都是服务器端 ...

  7. lucene索引并搜索mysql数据库[转]

    由于对lucene比较感兴趣,本人在网上找了点资料,终于成功地用lucene对mysql数据库进行索引创建并成功搜索,先总结如下: 首先介绍一个jdbc工具类,用于得到Connection对象: im ...

  8. 在android客户端加载html源代码总结

    在实际应用中,客户端要从网页上获取数据是常见的事,如果要解析网页上的html文档,那么首先得获取html源码,然后现在一般使用Jsoup来转换成Document文档来进行解析,本文主要讨论如何使用Js ...

  9. [TypeScript] Using Exclude and RootDir until File Globs Lands in 2.0.

    Files globs will be available in TypeScript 2.0, so in the meantime, we need to use "exclude&qu ...

  10. android 68 单元测试

    package com.itheima.junit; import android.os.Bundle; import android.app.Activity; import android.vie ...