部署DeepSeek模型,进群交流最in玩法!
立即加群
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >React Native调用原生UI组件

React Native调用原生UI组件

作者头像
xiangzhihong
发布于 2018-02-06 09:28:17
发布于 2018-02-06 09:28:17
1.6K00
代码可运行
举报
文章被收录于专栏:向治洪向治洪
运行总次数:0
代码可运行

React Native 中,其已经将几个常用的原生组件进行了封装,但是并不是所有系统的原始组件都被封装了,因此有时候我们不得不自己动手封装一下,从而能够使用那些React Native没有为我们封装的原生组件。为了方便讲解,我们选择第一个第三方库kenburnsview来讲解,kenburnsview是一个可以让图片在在页面移动或者放大缩小的库。

Android原生组件封装

1,继承SimpleViewManager,返回UI组件实例 首先,需要继承 SimpleViewManager 这个泛型类,和原生模块类似,需要重写 getName() 方法,将UI组件名称暴露给javascript层,接着需要重写 createViewInstance 方法,在里面返回需要使用的原生UI组件的实例。 2,暴露接口给javascript层调用 然后,就是暴露一些必要属性给javascript层,为了简单起见,我们这里只暴露两个属性,一个是 url ,一个是 html ,一旦javascript层设置了url,就会加载一个网页,而一旦设置了html,则会去加载这段html,而属性的暴露是使用注解。 为了方便,提供对应的set方法,之后在set方法中处理UI的更新操作。

代码实现

首先看一下效果: 首先新建一个RN项目,使用Anroid Studio开的Android项目,在build.gradle中添加kenburnsview库。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
compile 'com.flaviofaria:kenburnsview:1.0.7'

编写原生KenBurnsViewManager类,主要封装KenBurnsView的相关逻辑。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.rndemos;

import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.flaviofaria.kenburnsview.KenBurnsView;

import java.io.InputStream;


/**
 * Created by xiangzhihong on 2017/7/2.
 * React Native调用原生的Webiew组件
 */

public class KenBurnsViewManager extends SimpleViewManager<KenBurnsView> {

    public static final String REACT_CLASS = "KenBurnsView";
    private ThemedReactContext mContext=null;

    @Override
    public String getName() {
        return REACT_CLASS;
    }

    @Override
    protected KenBurnsView createViewInstance(ThemedReactContext reactContext) {
        mContext=reactContext;
        KenBurnsView kView= new KenBurnsView(reactContext);
        try {
            InputStream in=mContext.getAssets().open("shanghai.png");
            Drawable drawable=Drawable.createFromStream(in,null);
            kView.setImageDrawable(drawable);
        }catch (Exception e){
            e.printStackTrace();
        }
        return kView;
    }

    @ReactProp(name = "imageSource")
    public void setSource(KenBurnsView view,@Nullable String imagePath) {
        try {
            InputStream in=mContext.getAssets().open(imagePath);
            Drawable drawable=Drawable.createFromStream(in,null);
            view.setImageDrawable(drawable);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

实现ReactPackage接口,在createNativeModules函数中添加我们自定义的模块。该类的基本作用就是把继承的类的方法注册到JS里。相关代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.rndemos;

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.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by xiangzhihong on 2017/7/2.
 * 原生UI管理类
 */

public class KenBurnsViewPackage implements ReactPackage {

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new KenBurnsViewManager());
        return modules;
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }
}

熟悉原生模块的开发人员都知道,新建一个组件需要向系统注册。添加AppReactPackage 到ReactInstanceManager的实例中去,这里需要向MainActivity注册我们新建的组件(这是老版本的写法,新版本在Application注册)。MainActivity代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.rndemos;

import android.app.Application;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

import java.util.Arrays;
import java.util.List;

import static com.facebook.react.common.ApplicationHolder.getApplication;

public class MainApplication extends Application implements ReactApplication {


  private ReactRootView mReactRootView;
  private ReactInstanceManager mReactInstanceManager;

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage()
      );
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    initReactInstance();
  }
   //添加的代码
  //添加AppReactPackage 到ReactInstanceManager的实例中去
  public void initReactInstance(){
    mReactRootView = new ReactRootView(this);
    mReactInstanceManager = ReactInstanceManager.builder()
            .setApplication(getApplication())
            .setBundleAssetName("index.android.bundle")
            .setJSMainModuleName("index.android")
            .addPackage(new MainReactPackage())
            .addPackage(new AppReactPackage())
            .setUseDeveloperSupport(BuildConfig.DEBUG)
            .setInitialLifecycleState(LifecycleState.RESUMED)
            .build();

  }
}

不过需要注意的是0.41版本之后,注册组件的方法改到了Application。在Application中找到getPackages方法,然后加如下代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new AppReactPackage()
      );
    }

React Native实现

接下来,我们需要在javascript层新建一个js文件(ReactWebView,区分系统的WebView)。注意,在与index.android.js相同的目录下创建。KenBurnsView类相关代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import React, { Component,PropTypes } from 'react';
import {
    requireNativeComponent,
    NativeModules,
     View
} from 'react-native';

var iface = {
    name: 'KenBurnsView',
    propTypes: {
        imageSource: React.PropTypes.string,
        ...View.propTypes
    },
};

module.exports = requireNativeComponent('KenBurnsView', iface);

然后在Android中调用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var KenBurnView=require('./KenBurnsView');

let {width, height} = Dimensions.get("window");

export default class RNDemos extends Component {
    render() {
        return (
            <KenBurnView style={styles.imageStyle} imageSource='http://ohe65w0xx.bkt.clouddn.com/shanghai.png'/>
        );
    }
}

不过调用貌似有点问题。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-07-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
React Native调用原生组件
在React Native开发过程中,有时候我们可能需要访问平台的API,但react Native还没有相应的实现,或者是React Native还不支持一些原生的属性,我们需要调用原生代码来实现,或者是我们需要复用一些原来的Java代码,这个时候我们就需要创建一个原生模块来自己实现对我们需要功能的封装。 相关文档可以参照官方的介绍。 #实例 下面我们就通过实现一个自定义模块,来熟悉编写原生模块需要用的一些知识。该模块主要实现调用一些Android原生的功能,比如弹Toast,启动Activity等。
xiangzhihong
2018/01/26
1.8K0
React native和原生之间的通信
RN中文网关于原生模块(Android)的介绍可以看到,RN前端与原生模块之 间通信,主要有三种方法: 1)使用回调函数Callback,它提供了一个函数来把返回值传回给JavaScript。 2)使用Promise来实现。 3)原生模块向JavaScript发送事件。 关于使用回调,这是最简单的一种通信,这里可以看看官网的实现,今天要讲的是滴三种由原生模块向JavaScript发送事件。 (1)首先,你需要定义一个发送事件的方法。如下所示: /*原生模块可以在没有被调用的情况下往JavaScript发送事
xiangzhihong
2018/02/05
4.9K1
React native和原生之间的通信
React Native JSBundle拆包之原理篇
RN作为一款非常优秀的移动端跨平台开发框架,在近几年得到众多开发者的认可。纵观现在接入RN的大厂,如qq音乐、菜鸟、去哪儿,无疑不是将RN作为重点技术栈进行研发。
xiangzhihong
2022/11/30
3.3K0
从Android到React Native开发(二、通信与模块实现)
大家吼,(◐‿◑)作为失踪人口回归,这次第二期,就让我们来怼React Native的通信,快速实现单独的React Native模块到APP里,愉悦吧骚年。至于为什么要有这期?当然是为了愉悦的飙车啦ε-(´∀`; )。
GSYTech
2018/08/11
1.5K0
从Android到React Native开发(二、通信与模块实现)
React Native与Android 原生通信
我们用React Native 做混合开发的时候免不了要原生和React Native 进行通信交互,这篇文章就是分享原生模块与JS传递数据的几种方式。
HelloJack
2018/08/28
2.5K0
React Native使用原生组件
概述 有时候App需要访问平台API,但React Native可能还没有相应的模块包装;或者你需要复用一些Java代码,而不是用Javascript重新实现一遍;又或者你需要实现某些高性能的、多线程的代码,譬如图片处理、数据库、或者各种高级扩展等等。 我们知道React Native本身对这种偏业务和底层调用是不关心的,这时候我们就想到了原生组件,我们通过调用原生组件,然后经过特定的封装来达到效果。如我们在原生开发中常见的Toast为例: 原生模块封装 假设我们希望可以从Javascript发起一个T
xiangzhihong
2018/02/05
2.3K0
react native 调用原生UI组件
在React Native开发过程中,有时我们想要使用原生的一个UI组件或者是js比较难以实现的功能时,我们可以在react Naitve应用程序中封装和植入已有的原生组件。 本文我们实现一个VideoView的本地调用。 React Native并没有给我们提供VideoView这个组件,那我们要播放视频的话,有两种方法:一种是借助WebView,一种就是使用原生的播放器。 Java端实现 新建VideoViewManager类,并继承SimpleViewManager,SimpleViewManag
xiangzhihong
2018/02/06
7.5K1
react native 调用原生UI组件
react-native 打开设置界面
iOS iOS打开设置还是比较简单的,使用Linking组件即可: Linking.openURL('app-settings:') .catch(err => console.log('error', err)) Android 1、在android/app/src/main/java/com/<projectname>/文件夹下创建opensettings文件夹 2、在这个文件夹下创建模块文件OpenSettingsModule.java(模块功能)和包文件OpenSettingsPackage.
mcq
2018/06/27
2K0
React Native 启动速度优化 从Native方便着手
Web 开发有一个经典问题:「浏览器中从输入 URL 到页面渲染的这个过程中都发生了什么?」
conanma
2022/03/09
2.2K0
⏱ React Native 启动速度优化——Native 篇(内含源码分析)
Web 开发有一个经典问题:「浏览器中从输入 URL 到页面渲染的这个过程中都发生了什么?」
卤代烃
2021/04/26
2K0
⏱ React Native 启动速度优化——Native 篇(内含源码分析)
Android与RN层的交互
Android跳转到RN页面 由于主客是以插件化的方式集成功能插件的,所以在主客中Android跳转到RN页面需要plugin、module和component。plugin、module不过多解释,component对应的是具体的js页面,要成功启动此页面,需要在对应的RN二方库中注册此页面。例如:
xiangzhihong
2022/11/30
5900
React Native调用Android相机图库
概述 在很多的React Native开发中,我们需要调用原生的api实现调用相机和图库的功能,网上用的最多的开源库如:react-native-image-picker。关于react-native-image-picker的用法大家请看相关的文档。我们今天手动实现一份。 调用Android图库相机 创建项目 执行命令 : react-native init HeadImage 创建一个名为HeadImage的工程,可以使用命令先运行下Demo项目。 然后照一张图片,放到放到工程的 HeadImage\A
xiangzhihong
2018/01/26
1.8K0
react-native绑定优酷SDK-附效果图和源码
ReactNative绑定优酷SDK需要用到两部分知识: 优酷本身的sdk绑定; RN与原生界面的交互; 效果: RN版本:0.49.3 代码更新日期:2017.10.26 下文也根据绑定需要分为两部
磊哥
2018/05/08
9800
react-native绑定优酷SDK-附效果图和源码
React Native在Android当中实践(四)——代码集成
首先在项目根目录中创建一个空的index.js文件。(注意在0.49版本之前是index.android.js文件) index.js是React Native应用在Android上的入口文件。而且它是不可或缺的!
Demo_Yang
2018/10/15
9920
新版React Native 混合开发(Android篇)
在React Native的应用场景中,有时候一个APP只有部分页面是由React Native实现的,比如:我们常用的携程App,它的首页下的很多模块都是由React Native实现的,这种开发模式被称为混合开发。
CrazyCodeBoy
2020/04/24
7.6K0
ReactNative调用Android原生模块
有时候App需要访问平台API,但React Native可能还没有相应的模块包装;或者你需要复用一些Java代码,而不是用Javascript重新实现一遍;又或者你需要实现某些高性能的、多线程的代码,譬如图片处理、数据库、或者各种高级扩展等等。 我们把React Native设计为可以在其基础上编写真正的原生代码,并且可以访问平台所有的能力。要想实现访问Android原生API,总结一下,主要有以下几个步骤: 1. 创建一个原生模块 这个原生模块是一个继承ReactContextBaseJavaMod
xiangzhihong
2018/02/06
1.4K0
ReactNative For Android 框架启动核心路径剖析
QQ空间开发团队
2016/10/13
5.7K0
ReactNative For Android 框架启动核心路径剖析
现有Android项目引入ReactNative--九步大法
为什么写这篇文章,因为很多时候我们是需要在原Android工程中添加ReactNative,而不是直接react-native init hello来创建工程,而且官网的说明不是很详细,不是完全针对安卓的,所以本文的必要性不言而喻。
先知先觉
2019/01/21
1.2K0
React Native 混合开发(Android篇)
在React Native的应用场景中,有时候一个APP只有部分页面是由React Native实现的,比如:我们常用的携程App,它的首页下的很多模块都是由React Native实现的,这种开发模式被称为混合开发。
CrazyCodeBoy
2018/09/26
4.2K0
React Native运行原理解析
Facebook 于2015年9月15日推出react native for Android 版本, 加上2014年底已经开源的IOS版本,至此RN (react-native)真正成为跨平台的客户端框架。本篇主要是从分析代码入手,探讨一下RN在安卓平台上是如何构建一套JS的运行框架。 一、 整体架构 RN 这套框架让 JS开发者可以大部分使用JS代码就可以构建一个跨平台APP。 Facebook官方说法是learn once, run everywhere, 即在Android 、 IOS、 Browse
xiangzhihong
2018/02/05
6.3K0
React Native运行原理解析
推荐阅读
相关推荐
React Native调用原生组件
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验