React Native 中如何使用Android的第三方控件以Android的弹幕为例
来源:互联网 发布:什么软件看爱奇艺会员 编辑:程序博客网 时间:2024/05/21 10:11
Facebook的React Native 框架让我们移动端的民工眼前一亮啊,然而有个很蛋疼的问题就是目前react native提供的API目前有很多没办法满足我们,还好万能的react native为我们提供了自定义的方法,下面我们就一步一步的实现。
比如我们使用react native做一个弹幕。
1 首先我们在原生的Android找到先关的弹幕框架加入RN项目的Android端的依赖,这里我用的是github上的
compile 'com.github.ctiao:DanmakuFlameMaster:0.5.3'
2 然后我们就在Android中得到弹幕视图
package com.danmuView;import android.content.Context;import android.graphics.Color;import android.support.annotation.Nullable;import android.view.ContextThemeWrapper;import android.view.View;import com.facebook.react.bridge.ReactMethod;import com.facebook.react.uimanager.SimpleViewManager;import com.facebook.react.uimanager.ThemedReactContext;import com.facebook.react.uimanager.annotations.ReactProp;import java.util.Random;import master.flame.danmaku.controller.DrawHandler;import master.flame.danmaku.danmaku.model.BaseDanmaku;import master.flame.danmaku.danmaku.model.DanmakuTimer;import master.flame.danmaku.danmaku.model.IDanmakus;import master.flame.danmaku.danmaku.model.android.DanmakuContext;import master.flame.danmaku.danmaku.model.android.Danmakus;import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;import master.flame.danmaku.ui.widget.DanmakuView;/** * Created by cz on 2017/1/24. */public class DanmuView extends SimpleViewManager { private String MOUDLENAME = "DanmuView"; public static boolean showDanmaku; static Context context; //弹幕控制器 public static DanmakuContext danmakuContext; //弹幕view public static DanmakuView danmakuView; @Override public String getName() { return MOUDLENAME; } @Override protected View createViewInstance(ThemedReactContext reactContext) { context = reactContext; danmakuView = new DanmakuView(reactContext); //提升绘制效率 danmakuView.enableDanmakuDrawingCache(true); //设置回调 danmakuView.setCallback(new DrawHandler.Callback() { @Override public void prepared() { //准备完成开始显示 showDanmaku = false; danmakuView.start(); generateSomeDanmaku(); } @Override public void updateTimer(DanmakuTimer timer) { } @Override public void danmakuShown(BaseDanmaku danmaku) { } @Override public void drawingFinished() { } }); //创建DanmakuContext实例。DanmakuContext可以用于对弹幕的各种全局配置进行设定,如设置字体、设置最大显示行数等,这里我们设置为默认 danmakuContext = DanmakuContext.create(); //弹幕解析器 BaseDanmakuParser parser = new BaseDanmakuParser() { @Override protected IDanmakus parse() { return new Danmakus(); } }; danmakuView.prepare(parser, danmakuContext); return danmakuView; } /** * sp转px的方法。 */ public static int sp2px(float spValue) { final float fontScale =new ContextThemeWrapper(context,0).getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } /** * 向弹幕View中添加一条弹幕 * * @param content 弹幕的具体内容 * @param withBorder 弹幕是否有边框 */ public static void addDanmaku(String content, boolean withBorder) { BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL); danmaku.text = content; danmaku.padding = 5; danmaku.textSize = sp2px(20); danmaku.textColor = Color.WHITE; danmaku.setTime(danmakuView.getCurrentTime()); if (withBorder) { danmaku.borderColor = Color.GREEN; } danmakuView.addDanmaku(danmaku); } /** * 随机生成一些弹幕内容以供测试 */ public static void generateSomeDanmaku() { new Thread(new Runnable() { @Override public void run() { while (showDanmaku) { int time = new Random().nextInt(300); String content = "弹幕--nima" + time + time; addDanmaku(content, false); try { Thread.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @ReactProp(name = "needShow") public void setShowDanmu(DanmakuView danmakuView, @Nullable String needShow ){ if("Y".equals(needShow)){ danmakuView.show(); }else { danmakuView.hide(); } } @ReactMethod public void showDanmu(){ if(showDanmaku ){ showDanmaku =false; generateSomeDanmaku(); }else { showDanmaku=true; generateSomeDanmaku(); } } @ReactMethod public void destoryDanmu(){ showDanmaku = false; if (danmakuView != null) { danmakuView.release(); danmakuView = null; } }}
3 为js端提供module接口
package com.danmuView;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 cz on 2017/1/24. */public class DanmuViewReactPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { return Collections.emptyList(); } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Arrays.<ViewManager>asList( new DanmuView()); }}
4我们的弹幕接口已经封装完成,接下来我们需要对我们的弹幕进行控制,先把控制的方法封装完成
package com.danmuView;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.bridge.ReactContextBaseJavaModule;import com.facebook.react.bridge.ReactMethod;import static com.danmuView.DanmuView.addDanmaku;import static com.danmuView.DanmuView.danmakuView;import static com.danmuView.DanmuView.generateSomeDanmaku;import static com.danmuView.DanmuView.showDanmaku;/** * Created by cz on 2017/1/25. */public class DanmuControl extends ReactContextBaseJavaModule { private String MOUDLENAME = "DanmuControl"; public DanmuControl(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return MOUDLENAME; } @ReactMethod public void showDanmu(){ if(showDanmaku ){ showDanmaku =false; generateSomeDanmaku(); }else { showDanmaku=true; generateSomeDanmaku(); } } @ReactMethod public void addDanmu(String content, boolean withBorder){ System.out.println("chenzhu--->添加一条弹幕"); addDanmaku(content,withBorder); } @ReactMethod public void destoryDanmu(){ System.out.println("chenzhu--->销毁弹幕"); showDanmaku = false; if (danmakuView != null) { danmakuView.release(); danmakuView = null; } }}
5将我们的控制方法暴露给我们的js端
package com.danmuView;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 com.startactivitydemo.MyIntentModule;import java.util.Arrays;import java.util.Collections;import java.util.List;/** * Created by cz on 2017/1/25. */public class DanmuControlReactPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { return Arrays.<NativeModule>asList( new DanmuControl(reactContext)); } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); }}
6将我们自己封装的module注册到APPlocation中:
new DanmuViewReactPackage(),
new DanmuControlReactPackage(),
7我们在js端先建一个对应的view类
/** * Created by cz on 2017/1/24. */'use strict';import { PropTypes } from 'react';import { requireNativeComponent, View } from 'react-native';var iface = { name: 'DanmuView', propTypes: { needShow: PropTypes.string , ...View.propTypes // 包含默认的View的属性 },};export default module.exports = requireNativeComponent('DanmuView', iface);
然后就可以在你想是用的地方导入使用了,就和普通的控件类似的使用方法。
8 刚才我们还Android本地封装了控制弹幕的方法使用也是非常的方便:
onPress={()=>{ NativeModules.DanmuControl.addDanmu("添加一条弹幕测试--------",true);}}>
直接在你需要响应的事件下面通过NativeModules点上类名在点上方法名即可。
注意在封装modulepackg的时候返回的name要与你在js端自己定义的类名相同才能找到。
所以理论上Android能实现的功能react native都能实现,但是却丢失了react native的最初的意图,
不能完全的热更新了。所以大家在不到万不得已的情况下还是慎用
- React Native 中如何使用Android的第三方控件以Android的弹幕为例
- React Native优秀的第三方插件(Android & iOS)
- React Native优秀的第三方插件(Android & iOS)
- Android中第三方控件PhotoView的基本使用
- Android中第三方控件gifView的基本使用
- Android中第三方控件PhotoView的基本使用
- React-Native开发中常用的第三方控件持续更新
- Android第三方应用或者原生app内跳转React native的某个页面
- react native 常用的第三方工具包
- Android Studio 第三方库的导入「以 Volley 为例」
- Android第三方控件——百度地图的使用
- react native学习笔记9——引入第三方组件和react-navigation的使用
- Android studio导入第三方项目(以Volley为例)
- 在React Native项目中使用第三方库
- android 中 使用 第三方库AutoLayout动态设置控件的属性
- Android React Native的使用细节问题
- React Native Android Navigator的使用
- Android使用React Native 出现的问题
- 错误票据
- linux下如何将当前目录的文件名存到一个文本文件里
- Qt5 builds failing — missing /usr/local/.//mkspecs/macx-clang on macOS
- table中数据显示NaN问题。
- View Controller Transition:京东加购物车效果
- React Native 中如何使用Android的第三方控件以Android的弹幕为例
- android抓包测试
- 关于dialog引起的java.lang.IllegalArgumentException:View=com.android.internal.policy.impl.Ph
- Oracle SQL软硬解析
- cocoapods 一些基本问题遇到总结
- c++第二次实验:本月有几天?
- Handler系列一---存在问题,改进,使用之
- Spring boot CommandLineRunner的基本使用(一):启动加载数据
- .NET WebApi上传文件接口(带其他参数)