【中软国际】HarmonyOS 鸿蒙开源第三方组件-表情雨EmojiRain 原创 精华

中软国际AIoT开发者社区
发布于 2021-8-19 15:23
浏览
4收藏

背景

这是一个特别小巧的鸿蒙掉emoji表情包实现。效果类似于微信中发送"生日快乐"和"么么哒"之类的词语时触发的动画效果。

功能展示

基于鸿蒙系统,通过自定义控件属性方式实现了EmojiRain组件,同时支持java代码设置。

【中软国际】HarmonyOS 鸿蒙开源第三方组件-表情雨EmojiRain-鸿蒙开发者社区

原理解析

【中软国际】HarmonyOS 鸿蒙开源第三方组件-表情雨EmojiRain-鸿蒙开发者社区

如图所示,表情控件Image初始位置在屏幕的上方,EmojiRainLayout充满整个屏幕。
表情包开始掉落前,从指定表情包集合中获取对应元素,计算该元素本次掉落时的起始位置、终止位置、宽度、高度。
然后根据位置坐标及高度创建对应的动画对象,设置Animator.CurveType.ACCELERATE_DECELERATE动画插值器。
根据表情包掉落数量将Image元素准备完成后,通过调用addComponent()将Image添加到EmojiRainLayout上,达到覆盖在屏幕上的效果。
最后执行先加速后减速的动画效果,开启表情雨模式。

//使用rxjava控制动画执行间隔、执行顺序、执行对象
 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创建动画对象
 AnimatorProperty animatorProperty = emoji.createAnimatorProperty();
        //设置动画执行时长
        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);

使用说明

参数配置

  • per
    • 每一波掉落的emoji个数,默认6个
  • duration
    • 掉落动画持续的总时长,默认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();
  • 项目地址:EmojiRain

  • 作者:杜晨阳

更多原创内容请关注:中软国际 HarmonyOS 技术学院

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,共建鸿蒙生态,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
5
收藏 4
回复
举报
1条回复
按时间正序
/
按时间倒序
mb609898e2cfb86
mb609898e2cfb86

很实用的功能,基本每个应用都会用到。

1
回复
2021-8-20 09:51:12
回复
    相关推荐