HarmonyOS 鴻蒙開源第三方組件-表情雨EmojiRain
背景
這是一個特別小巧的鴻蒙掉emoji表情包實現(xiàn)。效果類似于微信中發(fā)送"生日快樂"和"么么噠"之類的詞語時觸發(fā)的動畫效果。
功能展示
基于鴻蒙系統(tǒng),通過自定義控件屬性方式實現(xiàn)了EmojiRain組件,同時支持java代碼設置。

原理解析

如圖所示,表情控件Image初始位置在屏幕的上方,EmojiRainLayout充滿整個屏幕。
表情包開始掉落前,從指定表情包集合中獲取對應元素,計算該元素本次掉落時的起始位置、終止位置、寬度、高度。
然后根據(jù)位置坐標及高度創(chuàng)建對應的動畫對象,設置Animator.CurveType.ACCELERATE_DECELERATE動畫插值器。
根據(jù)表情包掉落數(shù)量將Image元素準備完成后,通過調(diào)用addComponent()將Image添加到EmojiRainLayout上,達到覆蓋在屏幕上的效果。
最后執(zhí)行先加速后減速的動畫效果,開啟表情雨模式。
- //使用rxjava控制動畫執(zhí)行間隔、執(zhí)行順序、執(zhí)行對象
- Subscription subscription = Observable.interval(mDropFrequency, TimeUnit.MILLISECONDS)
- .take(mDuration / mDropFrequency)
- .flatMap(flow -> Observable.range(0, mEmojiPer))
- .map(image -> mEmojiPool.acquire())
- .filter(ep -> ep != null)
- .observeOn(OhosSchedulers.mainThread())
- .subscribe(this::startDropAnimationForSingleEmoji, Throwable::printStackTrace);
- mSubscriptions.add(subscription);
- //為Image創(chuàng)建動畫對象
- AnimatorProperty animatorProperty = emoji.createAnimatorProperty();
- //設置動畫執(zhí)行時長
- animatorProperty.setDuration((int)
- (mDropAverageDuration * Randoms.floatAround(1, RELATIVE_DROP_DURATION_OFFSET)));
- float startX = Randoms.getStartX();
- float endX = Randoms.getStopX();
- //指定動畫開始的坐標及終止坐標
- animatorProperty.moveFromX(startX).moveToX(endX).moveFromY(-imageHeight).moveToY(mWindowHeight);
- animatorProperty.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
- animatorProperty.start();
- //初始化Image,隨機賦予等比例縮放高度、寬度,指定圖片加載模式
- Image emoji = new Image(getContext());
- emoji.setImageElement(emojiDrawable);
- emoji.setScaleMode(Image.ScaleMode.CENTER);
- double positive = Randoms.positiveGaussian() * 0.6;
- final int width = (int) (emoji_standard_size * (1.0 + positive));
- final int height = (int) (emoji_standard_size * (1.0 + positive));
- final LayoutConfig params = new LayoutConfig(width, height);
- params.setMarginTop(-height);
- params.setMarginLeft((int) (-0.5F * width));
- emoji.setLayoutConfig(params);
使用說明
參數(shù)配置
per
- 每一波掉落的emoji個數(shù),默認6個
duration
- 掉落動畫持續(xù)的總時長,默認8000ms
dropDuration
- 每個emoji掉落時長的平均值,默認2400ms
dropFrequency
- 掉落頻率,即每兩撥的時間間隔,默認500ms
在layout中配置 EmojiRainLayout繼承自StackLayout,你完全可以把它當做原生的StackLayout使用。
- <com.luolc.emojirain.EmojiRainLayout
- xmlns:ohos="http://schemas.huawei.com/res/ohos"
- xmlns:app="http://schemas.huawei.com/res/ohos-auto"
- xmlns:tools="http://schemas.android.com/tools"
- ohos:height="match_parent"
- ohos:width="match_parent"
- app:dropDuration="2400"
- app:dropFrequency="500"
- app:duration="7200"
- app:per="10">
- <Text
- ohos:height="match_content"
- ohos:width="match_content"
- ohos:text="Hello world!" />
- </com.luolc.emojirain.EmojiRainLayout>
- public class MainAbilitySlice extends AbilitySlice {
- private EmojiRainLayout mContainer;
- @Override
- protected void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_main);
- // bind view
- mContainer = (EmojiRainLayout) findComponentById(ResourceTable.Id_group_emoji_container);
- // add emoji sources
- mContainer.addEmoji(ResourceTable.Media_emoji_1_3);
- mContainer.addEmoji(ResourceTable.Media_emoji_2_3);
- mContainer.addEmoji(ResourceTable.Media_emoji_3_3);
- mContainer.addEmoji(ResourceTable.Media_emoji_4_3);
- mContainer.addEmoji(ResourceTable.Media_emoji_5_3);
- // set emojis per flow, default 6
- mContainer.setPer(10);
- // set total duration in milliseconds, default 8000
- mContainer.setDuration(7200);
- // set average drop duration in milliseconds, default 2400
- mContainer.setDropDuration(2400);
- // set drop frequency in milliseconds, default 500
- mContainer.setDropFrequency(500);
- }
- }
開始掉落
- mContainer.startDropping();
停止掉落
- mContainer.stopDropping();