Mastering Complex Like-Button Animations on HarmonyOS vs Android with ArkUI
This article walks through implementing sophisticated like-button animations for a news client on HarmonyOS using ArkUI, compares the approach with Android's animation framework, explains key ArkUI APIs like animateTo, and provides detailed Kotlin and TypeScript code for property and Bezier curve animations.
Background Introduction
As the news client adapts to the HarmonyOS single‑framework system, more than 85% of functionality has been ported. To enhance interaction and visual experience, animation becomes essential. The article shows the Android live‑room like‑button effect (Figure 1) and the equivalent ArkUI animation on HarmonyOS (Figure 2).
ArkUI Animation API Overview
ArkUI offers comprehensive animation methods, including property, transition, particle, component, and frame animations. For this case, property animation is most suitable. ArkUI provides three property‑animation interfaces: animateTo, animation, and keyframeAnimateTo. The animateTo function is a generic API that animates state variables based on differences between the current and previous values.
animateTo(value: AnimateParam, event: () => void): void AnimateParamcan specify duration, curve, repeat count, callbacks, etc.
Android Implementation
The Android version uses a Bezier curve for the upward‑floating heart, combined with opacity and scale animations. A custom view adds an ImageView at runtime, then animates it. private fun addHeartImage() { The core of the path animation is a BezierEvaluator that implements the cubic‑Bezier formula.
class BezierEvaluator(private val controlPoint1: PointF, private val controlPoint2: PointF) : TypeEvaluator<PointF> {Random control points are generated to ensure each heart follows a unique curve.
val pointF1 = PointF(Random.nextInt(width - DensityUtils.dip2px(context, 35f)).toFloat(), ...)The getBezierAnimator method creates an ObjectAnimator that drives the x and y properties based on the Bezier evaluator.
private fun getBezierAnimator(targetView: View): ValueAnimator { ... }HarmonyOS Implementation
In HarmonyOS, ArkUI’s declarative UI requires a different approach. Instead of addView() / removeView(), the animation uses a state array and LazyForEach to render dynamic components. @ObservedV2 export class AnimationState { When the like button is clicked, a new AnimationState object is pushed into animaList, triggering LazyForEach to render an Image component.
this.animaList.pushData(new AnimationState(Date.now().toString()))The component’s onAppear handler starts the animation using animateTo, setting duration, curve, and callbacks for scaling, opacity, and progress.
animateTo({ duration: 1000, curve: Curve.Ease, iterations: 1, playMode: PlayMode.Normal, onFinish: () => { ... } })The movement is driven by a cubic‑Bezier calculation function.
private calculateCubicBezier(P0: number[], P1: number[], P2: number[], P3: number[], t: number): number[] { ... }When progress reaches 1, the item is removed from animaList, causing the component to disappear.
Conclusion
The article demonstrates how to create complex like‑button animations on both Android and HarmonyOS, highlighting the differences between imperative and declarative UI frameworks. Mastering ArkUI’s animation APIs enables smoother, more natural transitions in mobile applications.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
