HarmonyOS 鴻蒙開(kāi)源第三方組件-表情雨EmojiRain
想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
背景
這是一個(gè)特別小巧的鴻蒙掉emoji表情包實(shí)現(xiàn)。效果類似于微信中發(fā)送"生日快樂(lè)"和"么么噠"之類的詞語(yǔ)時(shí)觸發(fā)的動(dòng)畫效果。
功能展示
基于鴻蒙系統(tǒng),通過(guò)自定義控件屬性方式實(shí)現(xiàn)了EmojiRain組件,同時(shí)支持java代碼設(shè)置。

原理解析

如圖所示,表情控件Image初始位置在屏幕的上方,EmojiRainLayout充滿整個(gè)屏幕。
表情包開(kāi)始掉落前,從指定表情包集合中獲取對(duì)應(yīng)元素,計(jì)算該元素本次掉落時(shí)的起始位置、終止位置、寬度、高度。
然后根據(jù)位置坐標(biāo)及高度創(chuàng)建對(duì)應(yīng)的動(dòng)畫對(duì)象,設(shè)置Animator.CurveType.ACCELERATE_DECELERATE動(dòng)畫插值器。
根據(jù)表情包掉落數(shù)量將Image元素準(zhǔn)備完成后,通過(guò)調(diào)用addComponent()將Image添加到EmojiRainLayout上,達(dá)到覆蓋在屏幕上的效果。
最后執(zhí)行先加速后減速的動(dòng)畫效果,開(kāi)啟表情雨模式。
- //使用rxjava控制動(dòng)畫執(zhí)行間隔、執(zhí)行順序、執(zhí)行對(duì)象
- 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)建動(dòng)畫對(duì)象
- AnimatorProperty animatorProperty = emoji.createAnimatorProperty();
- //設(shè)置動(dòng)畫執(zhí)行時(shí)長(zhǎng)
- animatorProperty.setDuration((int)
- (mDropAverageDuration * Randoms.floatAround(1, RELATIVE_DROP_DURATION_OFFSET)));
- float startX = Randoms.getStartX();
- float endX = Randoms.getStopX();
- //指定動(dòng)畫開(kāi)始的坐標(biāo)及終止坐標(biāo)
- animatorProperty.moveFromX(startX).moveToX(endX).moveFromY(-imageHeight).moveToY(mWindowHeight);
- animatorProperty.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
- animatorProperty.start();
- //初始化Image,隨機(jī)賦予等比例縮放高度、寬度,指定圖片加載模式
- 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);
使用說(shuō)明
參數(shù)配置
per
- 每一波掉落的emoji個(gè)數(shù),默認(rèn)6個(gè)
duration
- 掉落動(dòng)畫持續(xù)的總時(shí)長(zhǎng),默認(rèn)8000ms
dropDuration
- 每個(gè)emoji掉落時(shí)長(zhǎng)的平均值,默認(rèn)2400ms
dropFrequency
- 掉落頻率,即每?jī)蓳艿臅r(shí)間間隔,默認(rèn)500ms
在layout中配置 EmojiRainLayout繼承自StackLayout,你完全可以把它當(dāng)做原生的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);
- }
- }
開(kāi)始掉落
- mContainer.startDropping();
停止掉落
- mContainer.stopDropping();
想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)