组件类型:UniNativeViewElement
自定义原生View组件
native-view自身没有渲染内容,开发者可以通过DOM API获取到native-view对应的原生view,然后提供平台原生view与native-view进行绑定,native-view将展示该view的渲染内容。
<native-view>组件是uni-app x下扩展原生组件(如map)的重要方式。事实上官方的map组件就是使用<native-view>开发的。详见下方的使用场景章节。
| Web | 微信小程序 | Android | iOS | HarmonyOS | HarmonyOS(Vapor) |
|---|---|---|---|---|---|
| x | x | 4.31 | 4.31 | 4.61 | 5.0 |
| 名称 | 类型 | 默认值 | 兼容性 | 描述 |
|---|---|---|---|---|
| @init | (event: UniNativeViewInitEvent) => void | - | native-view初始化时回调,event.detail = { element: 'native-view元素实例对象'} |
native-view 组件 init事件event
| 名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
|---|---|---|---|---|---|
| element | UniNativeViewElement | 是 | - | - | - |
native-view 适用于开发uts插件-标准模式组件
native-view提供 @init 监听元素初始化,通过事件UniNativeViewInitEvent的 detail.element 获取到 UniNativeViewElement。
Android 平台:
UniNativeViewElement 提供bindAndroidView函数与native-view绑定android平台原生view
IOS 平台:
UniNativeViewElement 提供bindIOSView函数与native-view绑定ios平台原生view
Harmony 平台:
UniNativeViewElement 提供 bindHarmonyWrappedBuilder / bindHarmonyFrameNode 函数与 native-view 绑定。
UniNativeViewElement 提供了dispatchEvent分发event事件API,注意:事件数据类型暂时只支持UniNativeViewEvent。
具体示例请参考:native-button插件,该插件使用native-view封装原生button实现的native-button。
native-view组件绑定原生view后自动适配组件全局属性native-view组件绑定原生view后自动适配组件全局事件 setOnTouchListener会导致touch部分全局事件失效native-view组件不支持自定义属性,使用uts插件-标准模式组件-声明属性props实现自定义属性目的native-view组件不支持子组件native-view组件不支持list-item复用机制,list-item其他子组件不受影响正常启动复用业务。native-view组件不支持background、border、boxshadow属性native-view组件不支持overflow属性设置visible,仅支持hidden不可以嵌套组件
展示使用 native-view 封装的原生view的UTS插件-标准模式组件 示例为hello uni-app x alpha分支,与最新HBuilderX Alpha版同步。与最新正式版同步的master分支示例另见
该 API 不支持 Web,请运行 hello uni-app x 到 App 平台体验
<template>
<scroll-view style="flex: 1;">
<page-intro content="本页演示 native-view 原生视图与 UTS 插件组件:调用组件方法、native-button 与容器、native-view 样式;可跳转 native-time-picker 等原生能力。"></page-intro>
<view style="padding-bottom: 50px;">
<!-- #ifndef APP-HARMONY -->
<text class="tips">说明:如果本地无 uts 插件编译环境请提交打包自定义基座查看效果</text>
<!-- #endif -->
<!-- #ifdef APP-HARMONY -->
<text class="tips"> </text>
<!-- #endif -->
<button type="primary" @tap="testCallMethod">调用组件方法</button>
<!-- native-button 通过 native-view 绑定原生button 实现的UTS插件-标准模式组件 -->
<native-button id="helloView" class="native-button" style="width: 200px; height: 100px;" :text="buttonText" @buttonTap="ontap"
@load="onload"></native-button>
<native-button-container></native-button-container>
<!-- #ifndef APP-HARMONY -->
<button type="primary" @click="gotoTimePicker">调用native-time-picker</button>
<!-- #endif -->
<text class="uni-title-text">native-view样式大合集</text>
<native-view class="styled-native-view"></native-view>
</view>
</scroll-view>
</template>
<script setup lang="uts">
import { createNativeButtonContext } from "@/uni_modules/native-button";
const buttonText = ref("native-button")
let isLoad = false
let clickCount = 0
function ontap(e : UniNativeViewEvent) {
uni.showToast({
title: "按钮被点击了"
})
clickCount ++
buttonText.value = "native-button"+clickCount
}
function onload() {
//标记已初始化 用于自动化测试
isLoad = true
}
//用于自动化测试
function getIsLoadTest():boolean {
return isLoad
}
function testCallMethod() {
let context = createNativeButtonContext("helloView")
context?.updateText("test code")
}
function gotoTimePicker() {
uni.openDialogPage({
url: "/pages/component/native-view/native-view-time-picker-dialog",
animationType: "fade-in"
})
}
defineExpose({getIsLoadTest})
</script>
<style>
.tips {
font-size: 14px;
color: #BEBEBE;
margin: 25px auto 25px auto;
text-align: center;
}
.native-button {
height: 100px;
width: 100px;
margin: 25px auto 25px auto;
}
.styled-native-view {
width: 80px;
height: 80px;
margin: 20px 30px;
padding: 5px;
border: 2px solid #007aff;
border-radius: 8px;
background-color: #f0f8ff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
opacity: 0.95;
position: relative;
transform: rotate(45deg);
}
</style>
通过 native-view 绑定原生 button 实现的UTS插件-标准模式组件 示例为hello uni-app x alpha分支,与最新HBuilderX Alpha版同步。与最新正式版同步的master分支示例另见
该 API 不支持 Web,请运行 hello uni-app x 到 App 平台体验
<template>
<!--建议只存在一个根节点,如果native-view存在兄弟节点则需要将其包裹处理-->
<view>
<native-view style="height: 100px;" @init="onviewinit" @customClick="ontap"></native-view>
<view style="width: 50%;height: 100px;">
<button>测试按钮</button>
</view>
</view>
</template>
<script setup lang="uts">
import { NativeButton } from "@/uni_modules/native-button";
let button : NativeButton | null = null
//声明属性
const props = defineProps<{ text : string }>()
//声明事件
const emit = defineEmits<{
(e : "load") : void
(e : "buttonTap", event : UniNativeViewEvent) : void
}>()
//声明方法
function updateText(value : string) {
button?.updateText(value)
}
//监听属性变化
watchEffect(() => {
const text = props.text
updateText(text)
})
//native-view初始化时触发此方法
function onviewinit(e : UniNativeViewInitEvent) {
//获取UniNativeViewElement 传递给NativeButton对象
button = new NativeButton(e.detail.element);
updateText(props.text)
emit("load")
}
function ontap(e : UniNativeViewEvent) {
emit("buttonTap", e)
}
function onUnmounted() {
// iOS平台需要主动释放 uts 实例
button?.destroy()
}
</script>
NativeButton原生对象代码如下:
Android
iOS
Harmony
import { Button } from "android.widget"
export class NativeButton {
$element: UniNativeViewElement;
constructor(element: UniNativeViewElement) {
this.$element = element;
this.bindView();
}
button: Button | null = null;
bindView() {
//通过UniElement.getAndroidActivity()获取android平台activity 用于创建view的上下文
this.button = new Button(this.$element.getAndroidActivity()!); //构建原生view
//限制原生Button 文案描述不自动大写
this.button?.setAllCaps(false)
//监听原生Button点击事件
this.button?.setOnClickListener(_ => {
const detail = {}
//构建自定义UniNativeViewEvent返回对象
const event = new UniNativeViewEvent("customClick", detail)
//响应分发原生Button的点击事件
this.$element.dispatchEvent(event)
})
//UniNativeViewEvent 绑定 安卓原生view
this.$element.bindAndroidView(this.button!);
}
updateText(text: string) {
//更新原生Button 文案描述
this.button?.setText(text)
}
destroy() {
//数据回收
}
}
具体示例请参考:native-button插件