tencent cloud

文档反馈

自定义原生组件

最后更新时间:2024-03-04 22:43:53
    小程序 SDK 的使用者可以自定义客户端原生组件为小程序提供支持。小程序开发者通过特定的小程序 API 能够在小程序页面中创建并操作原生组件以及与原生组件进行通信。Android 的客户端原生组件分为两种类型:
    非同层原生组件:原生组件渲染在小程序页面之上,不支持 zIndex,始终位于小程序其他组件上层并会遮挡小程序内容。该类型组件以普通 View 的形式进行绘制。
    同层原生组件:原生组件渲染在小程序页面内,支持 zIndex 以及页面内的组件层级关系。该类型组件需要以 Surface 的形式绘制在小程序页面中。
    
    小程序向页面中插入客户端自定义的组件需要先在 wxml 中引入一个 external-element 节点:
    <external-element
    id="comp1"
    type="maTestView"
    _insert2WebLayer="true"
    style="width: 200px;height: 100px;"
    bindexternalelementevent="handleEvent"
    ></external-element>
    此处 type 为与应用约定创建的组件类型名称一致,_insert2WebLayer 表示该组件为同层组件或者非同层组件(true 为同层,需客户端实现同层组件代理;false 为非同层,需要客户端实现非同层代理),bindexternalelementevent 可捕获 native 传递的 onExternalElementEvent 或者。onXWebExternalElementEvent,回调参数包括:
    {
    target,
    currentTarget,
    timeStamp,
    touches,
    detail, // native传递的参数
    }
    之后小程序通过 id 创建一个与该节点相关联的上下文:
    this.ctx = wx.createExternalElementContext('comp1');
    该方法会通知应用在节点的位置创建对应的原生组件。小程序后续可以通过该上下文向原生组件发送事件,对原生组件进行操作:
    this.ctx.call({
    params1: {
    name: 'name1',
    age: 11
    },
    params2: {
    name: 'name2',
    age: 22
    },
    success: (e) => {
    console.log('====operate success=====', e)
    },
    fail: (e) => {
    console.log('====operate fail=====', e)
    },
    complete: (e) => {
    console.log('====operate complete=====', e)
    }
    })
    应用的开发者需要实现特定的代理,在小程序调用自定义组件 API 时创建原生组件以及响应对原生组件的操作。以下会针对非同层组件以同层组件分别进行说明。

    自定义非同层原生组件

    通过如下设置覆写代理,宿主可以自定义创建非同层原生组件:
    @ProxyService(proxy = ExternalElementProxy.class)
    public class MyExternalElementProxy extends ExternalElementProxy{}
    代理需要实现以下内容:
    1. 插入非同层组件。当小程序向页面中插入非同层原生组件时会调用此方法。开发者需要实现此方法,并将自定义组件作为子 View 加入到 parent 参数提供的容器中。
    /** * 创建非同层组件,当小程序创建自定义非同层原生组件时将会调用此接口 * * @param widgetId 小程序创建的组件唯一ID * @param widgetContext 小程序组件的上下文,用于向小程序回传内容 * @param type 小程序创建的组件类型名称 * @param parent 承载原生组件的父容器 * @param params 小程序创建组件时传递的参数 */ public abstract void handleInsertElement(long widgetId, ExternalWidgetContext widgetContext, String type, ViewGroup parent, JSONObject params);
    2. 更新非同层组件。当原生组件在小程序中的位置以及大小发生变化时会调用此方法通知应用。原生组件的父容器布局会按照变化后的样式进行自适应,原生组件本身则可以根据需要对自身进行调整。
    /** * 更新非同层组件样式,当小程序更新自定义非同层原生组件的样式时将会调用此接口 * * @param widgetId 小程序组件ID * @param widgetContext 小程序组件的上下文,用于向小程序回传内容 * @param params 小程序更新组件时传递的参数 */ public abstract void handleUpdateElement(long widgetId, ExternalWidgetContext widgetContext, JSONObject params);
    3. 操作非同层组件。当小程序向原生组件发送事件时会调用此方法(例如按钮点击,状态变更),事件的具体内容需要开发者自行在 params 中进行定义。
    /** * 操作非同层组件,当小程序需要向非同层组件发送指令或者调用特有方法的时候将会调用此接口 * * @param widgetId 小程序组件ID * @param widgetContext 小程序组件的上下文,用于向小程序回传内容 * @param params 小程序更新组件时传递的参数 */ public abstract void handleOperateElement(long widgetId, ExternalWidgetContext widgetContext, JSONObject params);
    4. 删除非同层组件。当小程序删除已添加的原生组件时将调用此方法通知应用。此时组件的父容器将被移除,应用应当对组件进行销毁处理。
    /** * 删除非同层组件 * * @param widgetId 小程序组件ID * @param widgetContext 小程序组件的上下文,用于向小程序回传内容 */ public abstract void handleRemoveElement(long widgetId, ExternalWidgetContext widgetContext);

    小程序非同层原生组件上下文

    小程序组件的上下文包含了使原生组件能够向对应的小程序组件发送消息的方法。onExternalElementEvent 方法会直接向小程序发送 onExternalElementEvent 事件,小程序应该捕获并处理该事件;callbackSuccess、callbackFail 则是在小程序调用 API 向应用发送事件时对当次小程序 API 调用传入的 success 或者 fail 方法进行回调。
    /** * 向小程序发送 onExternalElementEvent 事件 * * @param jsonObject 事件携带的JSON数据 */ public final void onExternalElementEvent(JSONObject jsonObject); /** * 调用小程序提供的success回调方法 * * @param jsonObject 回调携带的JSON数据,可以为空 */ public final void callbackSuccess(JSONObject jsonObject); /** * 调用小程序提供的fail回调方法 * * @param jsonObject jsonObject 回调携带的JSON数据,可以为空 * @param message 错误信息描述 */ public final void callbackFail(JSONObject jsonObject, String message);

    自定义同层原生组件

    如果小程序请求创建的是同层原生组件,则需要应用实现以下代理:
    @ProxyService(proxy = ExternalEmbeddedWidgetClient.class)
    public class MyExternalEmbeddedElementProxy extends ExternalEmbeddedWidgetClient{}
    1. 与非同层组件不同,同层组件由于涉及到嵌入页面的 Surface 创建以及销毁,因此会提供额外的组件生命周期回调。开发者可以覆写这些方法对同层组件的生命周期事件进行处理:
    /** * 初始化同层组件DOM节点 * * @param context 页面上下文 * @param widgetId 同层组件ID * @param tagName 同层组件在DOM中的TAG * @param attributes 同层组件的Attributes */ public abstract void onInit(Context context, long widgetId, String tagName, Map<String, String> attributes); /** * 同层组件Surface创建完毕回调 * * @param widgetId 同层组件ID * @param surface 同层组件关联的Surface */ public abstract void onSurfaceCreated(long widgetId, Surface surface); /** * 同层组件Surface销毁回调 * * @param widgetId 同层组件ID * @param surface 同层组件关联的Surface */ public abstract void onSurfaceDestroyed(long widgetId, Surface surface); /** * 同层组件触摸事件回调 * * @param widgetId 同层组件ID * @param event 触摸事件 * @return 同层组件是否消费触摸事件 */ public abstract boolean onTouchEvent(long widgetId, MotionEvent event); /** * 同层组件绘制区域变化回调 * * @param widgetId 同层组件ID * @param rect 新的绘制区域 */ public abstract void onRectChanged(long widgetId, Rect rect); /** * 同层组件请求重绘 * * @param widgetId 同层组件ID */ public abstract void onRequestRedraw(long widgetId); /** * 同层组件可见性发生变化 * * @param widgetId 同层组件ID * @param visibility 是否可见 */ public abstract void onVisibilityChanged(long widgetId, boolean visibility); /** * 同层组件变为可用 * * @param widgetId 同层组件ID */ public abstract void onActive(long widgetId); /** * 同层组件变为不可用 * * @param widgetId 同层组件ID */ public abstract void onDeActive(long widgetId); /** * 同层组件节点被销毁 * * @param widgetId 同层组件ID */ public abstract void onDestroy(long widgetId); /** * 当前小程序页面进入pause状态 * * @param widgetId 同层组件ID */ public abstract void webViewPause(long widgetId); /** * 当前小程序页面进入resume状态 * * @param widgetId 同层组件ID */ public abstract void webViewResume(long widgetId); /** * 当前小程序页面被销毁 * * @param widgetId 同层组件ID */ public abstract void webViewDestroy(long widgetId); /** * 小程序进入resume状态 * * @param widgetId 同层组件ID */ public abstract void nativeResume(long widgetId); /** * 小程序进入pause状态 * * @param widgetId 同层组件ID */ public abstract void nativePause(long widgetId); /** * 小程序被销毁 * * @param widgetId 同层组件ID */ public abstract void nativeDestroy(long widgetId);
    2. 当小程序真正向页面插入同层组件时会调用应用的 handleInsertXWebExternalElement 接口。客户端开发应当实现该方法,根据 type 提供的组件类型将相应的组件绘制到 widgetId 关联的 Surface 上。
    /** * 插入同层组件 * * @param widgetId 同层组件ID * @param widgetContext 同层组件关联的小程序上下文 * @param type 同层组件类型 * @param req 同层组件透传参数 */ public abstract void handleInsertXWebExternalElement(long widgetId, ExternalWidgetContext widgetContext, String type, JSONObject req);
    3. 组件的大小以及样式发生变化时,会通过该方法通知应用:
    /** * 更新同层组件样式 * * @param widgetId 同层组件ID * @param widgetContext 同层组件关联的小程序上下文 * @param req 小程序传递的参数 */ public abstract void handleUpdateXWebExternalElement(long widgetId, XWebExternalWidgetContext widgetContext, JSONObject req);
    4. 当小程序组件向原生组件发送事件需要操作原生组件时会通过该方法通知应用:
    /** * 操作同层组件 * * @param widgetId 同层组件ID * @param widgetContext 同层组件关联的小程序上下文 * @param req 小程序传递的参数 */ public abstract void handleOperateXWebExternalElement(long widgetId, XWebExternalWidgetContext widgetContext, JSONObject req);
    5. 当小程序删除同层原生组件时会通过该方法通知应用:
    /** * 移除同层组件 * * @param widgetId 同层组件ID * @param widgetContext 同层组件关联的小程序上下文 */ public abstract void handleRemoveXWebExternalElement(long widgetId, XWebExternalWidgetContext widgetContext);

    小程序同层原生组件上下文

    与非同层组件类似,同层组件可以通过小程序组件的上下文向小程序发送 onXWebExternalElementEvent 事件;或是在小程序调用操作原生组件的 API 时回调 API 提供的 callback 方法。
    /** * 向小程序发送 onXWebExternalElementEvent 事件 * * @param jsonObject 事件携带的JSON数据 */ public final void onXWebExternalElementEvent(JSONObject jsonObject); /** * 调用小程序提供的success回调方法 * * @param jsonObject 回调携带的JSON数据,可以为空 */ public final void callbackSuccess(JSONObject jsonObject); /** * 调用小程序提供的fail回调方法 * * @param jsonObject jsonObject 回调携带的JSON数据,可以为空 * @param message 错误信息描述 */ public final void callbackFail(JSONObject jsonObject, String message);
    
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持