小程序 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 参数提供的容器中。
public abstract void handleInsertElement(long widgetId, ExternalWidgetContext widgetContext,
String type, ViewGroup parent, JSONObject params);
2. 更新非同层组件。当原生组件在小程序中的位置以及大小发生变化时会调用此方法通知应用。原生组件的父容器布局会按照变化后的样式进行自适应,原生组件本身则可以根据需要对自身进行调整。
public abstract void handleUpdateElement(long widgetId, ExternalWidgetContext widgetContext,
JSONObject params);
3. 操作非同层组件。当小程序向原生组件发送事件时会调用此方法(例如按钮点击,状态变更),事件的具体内容需要开发者自行在 params 中进行定义。
public abstract void handleOperateElement(long widgetId, ExternalWidgetContext widgetContext,
JSONObject params);
4. 删除非同层组件。当小程序删除已添加的原生组件时将调用此方法通知应用。此时组件的父容器将被移除,应用应当对组件进行销毁处理。
public abstract void handleRemoveElement(long widgetId, ExternalWidgetContext widgetContext);
小程序非同层原生组件上下文
小程序组件的上下文包含了使原生组件能够向对应的小程序组件发送消息的方法。onExternalElementEvent 方法会直接向小程序发送 onExternalElementEvent 事件,小程序应该捕获并处理该事件;callbackSuccess、callbackFail 则是在小程序调用 API 向应用发送事件时对当次小程序 API 调用传入的 success 或者 fail 方法进行回调。
public final void onExternalElementEvent(JSONObject jsonObject);
public final void callbackSuccess(JSONObject jsonObject);
public final void callbackFail(JSONObject jsonObject, String message);
自定义同层原生组件
如果小程序请求创建的是同层原生组件,则需要应用实现以下代理:
@ProxyService(proxy = ExternalEmbeddedWidgetClient.class)
public class MyExternalEmbeddedElementProxy extends ExternalEmbeddedWidgetClient{}
1. 与非同层组件不同,同层组件由于涉及到嵌入页面的 Surface 创建以及销毁,因此会提供额外的组件生命周期回调。开发者可以覆写这些方法对同层组件的生命周期事件进行处理:
public abstract void onInit(Context context, long widgetId, String tagName, Map<String, String> attributes);
public abstract void onSurfaceCreated(long widgetId, Surface surface);
public abstract void onSurfaceDestroyed(long widgetId, Surface surface);
public abstract boolean onTouchEvent(long widgetId, MotionEvent event);
public abstract void onRectChanged(long widgetId, Rect rect);
public abstract void onRequestRedraw(long widgetId);
public abstract void onVisibilityChanged(long widgetId, boolean visibility);
public abstract void onActive(long widgetId);
public abstract void onDeActive(long widgetId);
public abstract void onDestroy(long widgetId);
public abstract void webViewPause(long widgetId);
public abstract void webViewResume(long widgetId);
public abstract void webViewDestroy(long widgetId);
public abstract void nativeResume(long widgetId);
public abstract void nativePause(long widgetId);
public abstract void nativeDestroy(long widgetId);
2. 当小程序真正向页面插入同层组件时会调用应用的 handleInsertXWebExternalElement 接口。客户端开发应当实现该方法,根据 type 提供的组件类型将相应的组件绘制到 widgetId 关联的 Surface 上。
public abstract void handleInsertXWebExternalElement(long widgetId, ExternalWidgetContext widgetContext, String type, JSONObject req);
3. 组件的大小以及样式发生变化时,会通过该方法通知应用:
public abstract void handleUpdateXWebExternalElement(long widgetId, XWebExternalWidgetContext widgetContext, JSONObject req);
4. 当小程序组件向原生组件发送事件需要操作原生组件时会通过该方法通知应用:
public abstract void handleOperateXWebExternalElement(long widgetId, XWebExternalWidgetContext widgetContext, JSONObject req);
5. 当小程序删除同层原生组件时会通过该方法通知应用:
public abstract void handleRemoveXWebExternalElement(long widgetId, XWebExternalWidgetContext widgetContext);
小程序同层原生组件上下文
与非同层组件类似,同层组件可以通过小程序组件的上下文向小程序发送 onXWebExternalElementEvent 事件;或是在小程序调用操作原生组件的 API 时回调 API 提供的 callback 方法。
public final void onXWebExternalElementEvent(JSONObject jsonObject);
public final void callbackSuccess(JSONObject jsonObject);
public final void callbackFail(JSONObject jsonObject, String message);
本页内容是否解决了您的问题?