uniapp 原生插件开发 UI

前言:

在集成某些特定 原生SDK的时候,它本身是带UI控件的。当我们使用 uniapp 开发app的时候实是 可以使使用 nvue 页面,以 weex 的方式嵌入原生的UI控件。

我这边的场景是 接入连连app的支付,它有个自己的密码键盘 控件是原生的页面。这里就需要用到 nvue 以 weex 的方式接入:

图中

蓝色部分为 sdk 密码控件输入框,下面弹出的软键盘为 SDK 自带密码键盘; 函数为密码键盘SDK提供的函数

官方文档解析:

查看官方文档:

开发者须知 | uni小程序SDK

public class TestText extends UniComponent<TextView>

只要继承 UniComponent 的控件 就可以了,但是这里有个插曲。 代码自动生成的 构造函数多了一个参数。造成框架初始化 weex 组件(原始组件)不成功 " com.taobao.weex.common.xRuntimeException: can't find constructor of component"

///错误的 四个参数
public InputLianLian(UniSDKInstance instance, AbsVContainer parent, int type, AbsComponentData componentData) {
    super(instance, parent, type, componentData);
}

///正确的 三个参数
public InputLianLian(UniSDKInstance instance, AbsVContainer parent, AbsComponentData componentData) {
    super(instance, parent, componentData);
    AbsAttr attr = componentData.getAttrs();
    aesKey = (String) attr.get("aesKey");
    rasKey = (String) attr.get("rsaPublic");
}

在 initComponentHostView 中返回你的控件就可以了

@Override
protected PassGuardEdit initComponentHostView(@NonNull Context context) {
    inputEditText = new PassGuardEdit(context, null);
    inputEditText.setButtonPress(true);
    if ((aesKey != null && aesKey.length() > 0) && (rasKey != null && rasKey.length() > 0)) {
        inputEditText.setCipherKey(aesKey);
        inputEditText.setPublicKey(rasKey);
    }
    inputEditText.needScrollView(false);
    inputEditText.setButtonPressAnim(true);
    //6-12位的字母、数字,不可以是连续或者重复的数字和字母
    inputEditText.setInputRegex("[a-zA-Z0-9]{1,12}");
    //inputEditText.setInputRegex("[0-9]{1,6}");
    inputEditText.setClip(false);
    inputEditText.setMaxLength(12);//12位
    //inputEditText.useNumberPad(true);//纯数字
    inputEditText.setWatchOutside(true);
    inputEditText.initPassGuardKeyBoard();
    return inputEditText;
}

上手实操:

如果你是云打包,那么就需要把插件写成 模块库 的方式开发。方便导出 .aar库 给其他程序使用 。如果你是本地打包 那么直接写就好了。我这边是云打包,开发的时候 是本地跑的方式。

脚本依赖:

因为我们 是以 库的方式开发的,本身工程文件最好不好防止三方依赖库。我们都依赖 主应用的三方库;

. InputLianLian.java 完整控件脚本

package com.john.bridge.component;
import android.content.Context;
import androidx.annotation.NonNull;
import cn.passguard.PassGuardEdit;
import io.dcloud.feature.uniapp.UniSDKInstance;
import io.dcloud.feature.uniapp.annotation.UniJSMethod;
import io.dcloud.feature.uniapp.bridge.UniJSCallback;
import io.dcloud.feature.uniapp.dom.AbsAttr;
import io.dcloud.feature.uniapp.ui.action.AbsComponentData;
import io.dcloud.feature.uniapp.ui.component.AbsVContainer;
import io.dcloud.feature.uniapp.ui.component.UniComponent;

public class InputLianLian extends UniComponent<PassGuardEdit> {
    private PassGuardEdit inputEditText;
    private String aesKey;
    private String rasKey;

public InputLianLian(UniSDKInstance instance, AbsVContainer parent, AbsComponentData componentData) {
    super(instance, parent, componentData);
    AbsAttr attr = componentData.getAttrs();
    aesKey = (String) attr.get("aesKey");
    rasKey = (String) attr.get("rsaPublic");
}

@Override
protected PassGuardEdit initComponentHostView(@NonNull Context context) {
    inputEditText = new PassGuardEdit(context, null);
    inputEditText.setButtonPress(true);
    if ((aesKey != null && aesKey.length() > 0) && (rasKey != null && rasKey.length() > 0)) {
        inputEditText.setCipherKey(aesKey);
        inputEditText.setPublicKey(rasKey);
    }
    inputEditText.needScrollView(false);
    inputEditText.setButtonPressAnim(true);
    //6-12位的字母、数字,不可以是连续或者重复的数字和字母
    inputEditText.setInputRegex("[a-zA-Z0-9]{1,12}");
    //inputEditText.setInputRegex("[0-9]{1,6}");
    inputEditText.setClip(false);
    inputEditText.setMaxLength(12);//12位
    //inputEditText.useNumberPad(true);//纯数字
    inputEditText.setWatchOutside(true);
    inputEditText.initPassGuardKeyBoard();
    return inputEditText;
}

    @UniJSMethod
    public void initEditText(String aesKey, String rasKey) {
        if ((aesKey != null && aesKey.length() > 0) && (rasKey != null && rasKey.length() > 0)) {
            inputEditText.setCipherKey(aesKey);
            inputEditText.setPublicKey(rasKey);
            inputEditText.initPassGuardKeyBoard();
        }
    }

    @UniJSMethod(uiThread = true)
    public void getInputMD5(UniJSCallback callback) {
        if (callback != null && inputEditText != null) {
            callback.invoke(inputEditText.getMD5());
        }
    }

    @UniJSMethod(uiThread = true)
    public void getInputLength(UniJSCallback callback) {
        if (callback != null && inputEditText != null) {
            callback.invoke(inputEditText.getLength());
        }
    }

    @UniJSMethod(uiThread = true)
    public void getInputRSAAES(UniJSCallback callback) {
        if (callback != null && inputEditText != null) {
            callback.invoke(inputEditText.getRSAAESCiphertext ());
        }
    }
}
配置 weex 控件 dcloud_uniplugins.json

因为 uniapp 是通过我们这个配置表 来加载 weex 控件的;要么通过代码的方式也是可以的,这里两张都介绍下。应为你要告诉你的 主APP 你都有哪些 自定义的 weex 控件:

配置文件:
代码的方式:

基本上差不多了,已经跑起来了

我们再来看 .nvue 的页面

组件 inputLianLian 直接使用,方法调用,以及参数传值。

<template>
	<div class="mian">
		<div>
			<!-- 直接传入 aesKey rasKey 初始化控件 -->
			<inputLianLian ref='inputLianLian' :aesKey="aesKey" :rasKey="rasKey"
				style="width:690rpx;height:120rpx;background-color: aqua;">
			</inputLianLian>

			<div @click="getMD5()" style="width: 200;height: 80rpx; background-color: azure;">getMD5</div>
			<div @click="getLength()" style="width: 200;height: 80rpx;background-color:bisque;">getLength</div>
			<div @click="getLInputAESCode()" style="width: 200;height: 80rpx;background-color:coral;">getLInputAESCode
			</div>
			<div @click="initLianLian()" style="width: 200;height: 80rpx;background-color:darkgray;">initLianLian</div>
		</div>
	</div>
</template>

<script>
	import md5 from 'uview-ui/libs/function/md5';
	export default {
		data() {
			return {
				aesKey: '26999721009008604284404453805522',
				rasKey: '3081890281810092D9D8D04FB5F8EF9B8374F21690FD46FDBF49B40EECCDF416B4E2AC2044B0CFE3BD67EB4416B26FD18C9D3833770A526FD1AB66A83ED969AF74238D6C900403FC498154EC74EAF420E7338675CAD7F19332B4A56BE4FF946B662A3C2D217EFBE4DC646FB742B8C62BFE8E25FD5DC59E7540695FA8B9CD5BFD9F92DFAD009D230203010001'
			}
		},
		methods: {
			///二次初始化,刚进来拿不到初始化参数 参数情况下 ,
			///如果输入框不能二次初始化,等待拿到数据再展示
			initLianLian() {
				this.$refs.inputLianLian.initEditText('aesKey', 'rasKey');
			},
			async getMD5() {
				this.$refs.inputLianLian.getInputMD5((md5) => {
					uni.showToast({
						title: `md5:${md5}`,
						duration: 3000
					});
				});

				const md5 = await getInputMD5();
				uni.showModal({
					content: `md5:${md5}`,
				})
			},
			getLength() {
				this.$refs.inputLianLian.getInputLength((length) => {
					uni.showToast({
						title: `length:${length}`,
						duration: 3000
					});
				});
			},
			getLInputAESCode() {
				this.$refs.inputLianLian.getInputRSAAES((code) => {
					uni.showToast({
						title: `code:${code}`,
						duration: 3000
					});
				});
			},
			getInputMD5() {
				return new Promise((resolve, reject) => {
					try {
						this.$refs.inputLianLian.getInputMD5((md5) => {
							console.log('onMD5:', md5)
							resolve(md5);
						})
					} catch (ex) {
						console.log('onMD5 error:', ex)
						//reject('')
						resolve('');
					}
				});
			}
		}
	}
</script>

<style>
	.mian {
		display: flex;
		flex-direction: column;
		align-items: center;
	}
</style>
设置weex脚本 不混淆

因为 weex 加载是通过,反射的方式加载的。如果脚本混淆了,脚本的配置文件就对应不上了

导出 .aar 给云打包使用:

这里我们需要工程 导出为 .aar

在uniapp中设置 原生插件: 主要两个目录:

---android 放置 .aar

--- libs 放置 .jar 和 对应的 .so ; .so 文件按照 CPU 目录放置

插件描述文件 : 和 上面的 dcloud_uniplugins.json 有点像

配置没有错误:这里就能展示出来了

相关推荐
DK七七17 小时前
当今陪玩系统小程序趋势,陪玩系统源码搭建后的适用于哪些平台
小程序·php·uniapp
漫天转悠2 天前
Uniapp在Vue环境中引入iconfont图标库(详细教程)
前端·vue.js·uniapp
ZSK63 天前
【uniapp3】分享一个自己写的h5日历组件
vue·uniapp
wang_book4 天前
uniapp学习(010-2 实现抖音小程序上线)
前端·javascript·小程序·vue·uniapp
小金子J11 天前
微信小程序地图功能开发:绘制多边形和标记点
javascript·微信小程序·小程序·uniapp
一只欢喜11 天前
前端处理API接口故障:多接口自动切换的实现方案
前端·javascript·vue.js·uniapp
困了就睡一会13 天前
uniapp uview 上传图片,数据以formData + File 形式传输
uniapp·js·1024程序员节
晚睡要秃头15 天前
通过微信小程序实现对接企业微信客服
javascript·微信小程序·vue·企业微信·uniapp
Qiuner17 天前
从0到1!萌新跟着操作也能学会的保姆级全栈项目开发实录一:项目初始化配置
vue·springboot·uniapp·ruoyi