harmony 鸿蒙使用动画
使用动画
使用属性动画
ArkUI开发框架在NDK接口主要提供属性动画,实现组件出现/消失转场。同时,可以通过Node-API桥接ArkTS侧帧动画能力,实现Native侧的动画效果。
说明:
需要从ArkTS侧获取this.getUIContext(),传入到Native侧。
在Native侧通过OH_ArkUI_GetContextFromNapiValue方法获取context。
需要执行的动画属性变化必须写在ArkUI_ContextCallback中callback中。
需要执行的动画属性,必须在执行动画之前设置过。
提供全局animateTo显式动画接口,来指定由于闭包代码导致的状态变化插入过渡动效。同属性动画,布局类改变宽高的动画,内容都是直接到终点状态。
在.ets文件中获取UIContext,把this.getUIContext()当做参数输出到Native方法中。
// createNativeNode是Native侧暴露的方法 nativeNode.createNativeNode("xcomponentId", this.getUIContext());
解析UIContext转换C中的context对象。
// 获取ets测传入的context ArkUI_ContextHandle context = nullptr; // 通过code 判断是否获取成功 auto code = OH_ArkUI_GetContextFromNapiValue(env, args[1], &context);
获取ArkUI_NativeAnimateAPI_1 对象。
// 获取ArkUI_NativeAnimateAPI接口 ArkUI_NativeAnimateAPI_1 *animateApi = nullptr; OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_ANIMATE, ArkUI_NativeAnimateAPI_1, animateApi);
设置 ArkUI_AnimateOption参数,通过提供的C方法设置对应的参数。
ArkUI_AnimateOption *option = OH_ArkUI_AnimateOption_Create(); OH_ArkUI_AnimateOption_SetDuration(option, 2000); OH_ArkUI_AnimateOption_SetTempo(option, 1.1); OH_ArkUI_AnimateOption_SetCurve(option, ARKUI_CURVE_EASE); OH_ArkUI_AnimateOption_SetDelay(option, 20); OH_ArkUI_AnimateOption_SetIterations(option, 1); OH_ArkUI_AnimateOption_SetPlayMode(option, ARKUI_ANIMATION_PLAY_MODE_REVERSE); ArkUI_ExpectedFrameRateRange *range = new ArkUI_ExpectedFrameRateRange; range->min = 10; range->max = 120; range->expected = 60; OH_ArkUI_AnimateOption_SetExpectedFrameRateRange(option, range);
设置回调参数。
// 用户自定义参数 struct UserData{ int32_t data; }; UserData *onFinishUser = new UserData; onFinishUser->data= 101; // 设置完成的回调 ArkUI_AnimateCompleteCallback *completeCallback = new ArkUI_AnimateCompleteCallback; completeCallback->userData = onFinishUser; completeCallback->type = ARKUI_FINISH_CALLBACK_REMOVED; completeCallback->callback = [](void *userData) { OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode onFinishCallback %{public}d", reinterpret_cast<AA *>(userData)->a); }; // 用户自定义参数 UserData *eventUser = new UserData ; eventUser->data= 201; static bool isback = true; ArkUI_ContextCallback *update = new ArkUI_ContextCallback; update->userData = eventUser; update->callback = [](void *user) { OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode animateTo %{public}d", reinterpret_cast<UserData*>(user)->data); // 对应的属性变化 width height if (isback) { ArkUI_NumberValue custom_widthValue[] = {200}; ArkUI_AttributeItem custom_widthItem = {custom_widthValue, 1}; ArkUI_NumberValue custom_heightValue1[] = {80}; ArkUI_AttributeItem custom_heightItem1 = {custom_heightValue1, 1}; nodeAPI->setAttribute(textInput, NODE_WIDTH, &custom_widthItem); nodeAPI->setAttribute(textInput, NODE_HEIGHT, &custom_heightItem1); } else { ArkUI_NumberValue custom_widthValue[] = {100}; ArkUI_AttributeItem custom_widthItem = {custom_widthValue, 1}; ArkUI_NumberValue custom_heightValue1[] = {40}; ArkUI_AttributeItem custom_heightItem1 = {custom_heightValue1, 1}; nodeAPI->setAttribute(textInput, NODE_WIDTH, &custom_widthItem); nodeAPI->setAttribute(textInput, NODE_HEIGHT, &custom_heightItem1); } }; // 执行对应的动画 animateApi->animateTo(context, option, update, completeCallback);
组件出现/消失转场
组件内转场通过NODE_XX_TRANSITION属性(XX包括:OPACITY、TRANSLATE、SCALE、ROTATE、MOVE)配置转场参数,在组件插入和删除时显示过渡动效(通过NODE_TRANSFORM_CENTER属性设置NODE_SCALE_TRANSITION和NODE_ROTATE_ROTATE动效的中心点坐标)。主要用于容器组件中子组件插入和删除时,提升用户体验。
- 创建可交互界面,界面中包含Button,点击可以控制转场节点的添加和移除。其中 ArkUI_NodeContentHandle 类型节点的获取与使用可参考接入ArkTS页面。 “` constexpr int32_t BUTTON_CLICK_ID = 1; bool flag = false; ArkUI_NodeHandle parrentNode; ArkUI_NodeHandle childNode; ArkUI_NodeHandle buttonNode;
void mainViewMethod(ArkUI_NodeContentHandle handle)
{
ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast
2. 创建一个设置了Transition属性的节点,当目标节点上下树时会播放转场动画。
ArkUI_NodeHandle CreateChildNode() {
ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast
3. 在Button的监听回调里添加转场节点上下树逻辑,以此控制转场节点的入场和出场。
void OnButtonShowClicked(ArkUI_NodeEvent* event)
{
if (!event) {
return;
}
if (!childNode) {
childNode = CreateChildNode();
}
ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast

## 使用关键帧动画
[keyframeAnimateTo](../reference/apis-arkui/_ark_u_i___native_animate_a_p_i__1.md#keyframeanimateto)接口来指定若干个关键帧状态,实现分段的动画。同属性动画,布局类改变宽高的动画,内容都是直接到终点状态。
该示例主要演示如何通过[keyframeAnimateTo](../reference/apis-arkui/_ark_u_i___native_animate_a_p_i__1.md#keyframeanimateto)来设置关键帧动画,NDK接口开发的UI界面挂载到ArkTS主页面的完整流程可参考[接入ArkTS页面](https://m.seaxiang.com/blog/Yyd7qk)。
auto column = nodeAPI->createNode(ARKUI_NODE_COLUMN);
// 创建button,后续创建的关键帧动画作用在button组件上 auto button = nodeAPI->createNode(ARKUI_NODE_BUTTON); ArkUI_NumberValue widthValue0[] = {100}; ArkUI_AttributeItem widthItem0 = {widthValue0, 1}; ArkUI_NumberValue heightValue0[] = {100}; ArkUI_AttributeItem heightItem0 = {heightValue0, 1}; nodeAPI->setAttribute(button, NODE_WIDTH, &widthItem0); nodeAPI->setAttribute(button, NODE_HEIGHT, &heightItem0); ArkUI_NumberValue typeValue[] = {{.i32 = ArkUI_ButtonType::ARKUI_BUTTON_TYPE_CIRCLE}}; ArkUI_AttributeItem typeItem = {typeValue, 1}; nodeAPI->setAttribute(button, NODE_BUTTON_TYPE, &typeItem); // 设置button的形状为圆形
static ArkUI_NodeHandle buttonSelf = button; static ArkUI_NativeNodeAPI_1 *nodeAPISelf = nodeAPI;
// 注册点击事件到button上 nodeAPI->registerNodeEvent(button, NODE_ON_CLICK, 1, nullptr); auto onTouch = [](ArkUI_NodeEvent *event) {
// 点击button按钮时触发该逻辑
if (OH_ArkUI_NodeEvent_GetTargetId(event) == 1) {
// 获取context对象
static ArkUI_ContextHandle context = nullptr;
context = OH_ArkUI_GetContextByNode(buttonSelf);
// 获取ArkUI_NativeAnimateAPI接口
ArkUI_NativeAnimateAPI_1 *animateApi = nullptr;
OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_ANIMATE, ArkUI_NativeAnimateAPI_1, animateApi);
// 以下代码为创建关键帧动画的关键流程,包括设置关键帧动画参数、开启关键帧动画
// 设置ArkUI_KeyframeAnimateOption参数,通过提供的C方法设置对应的参数
static ArkUI_KeyframeAnimateOption *option = OH_ArkUI_KeyframeAnimateOption_Create(2); // 关键帧动画状态数
OH_ArkUI_KeyframeAnimateOption_SetDuration(option, 1000, 0); // 第一段关键帧动画的持续时间
OH_ArkUI_KeyframeAnimateOption_SetDuration(option, 2000, 1); // 第二段关键帧动画的持续时间
OH_ArkUI_KeyframeAnimateOption_SetIterations(option, 5); // 关键帧动画播放次数
OH_ArkUI_KeyframeAnimateOption_RegisterOnEventCallback(option, nullptr, [](void *user) {
ArkUI_NumberValue widthValue0[] = {150};
ArkUI_AttributeItem widthItem0 = {widthValue0, 1};
ArkUI_NumberValue heightValue0[] = {150};
ArkUI_AttributeItem heightItem0 = {heightValue0, 1};
nodeAPISelf->setAttribute(buttonSelf, NODE_WIDTH, &widthItem0);
nodeAPISelf->setAttribute(buttonSelf, NODE_HEIGHT, &heightItem0);
}, 0); // 第一段关键帧时刻状态的闭包函数
OH_ArkUI_KeyframeAnimateOption_RegisterOnEventCallback(option, nullptr, [](void *user) {
ArkUI_NumberValue widthValue0[] = {80};
ArkUI_AttributeItem widthItem0 = {widthValue0, 1};
ArkUI_NumberValue heightValue0[] = {80};
ArkUI_AttributeItem heightItem0 = {heightValue0, 1};
nodeAPISelf->setAttribute(buttonSelf, NODE_WIDTH, &widthItem0);
nodeAPISelf->setAttribute(buttonSelf, NODE_HEIGHT, &heightItem0);
}, 1); // 第二段关键帧时刻状态的闭包函数
OH_ArkUI_KeyframeAnimateOption_RegisterOnFinishCallback(option, nullptr, [](void *user) {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "keyframe animate finish");
}); // 关键帧动画结束回调
ArkUI_ExpectedFrameRateRange *range = new ArkUI_ExpectedFrameRateRange;
range->max = 120;
range->expected = 60;
range->min = 30;
OH_ArkUI_KeyframeAnimateOption_SetExpectedFrameRate(option, range); // 关键帧设置期望帧率
// 执行对应的动画
animateApi->keyframeAnimateTo(context, option);
}
}; nodeAPI->registerNodeEventReceiver(onTouch); nodeAPI->addChild(column, button); “`
你可能感兴趣的鸿蒙文章
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦