仿蚂蚁森林能量球效果遇到的问题记录

仿蚂蚁森林能量球效果遇到的问题记录

常规先上图
这里写图片描述

前提内容

仿做一个蚂蚁森林的能量球效果,计划使用属性动画,来实现能量球上下摆动,然后点击能量球有一个收集的动画。

本来以为就这么几个简单的需求不会太难,做完后发现问题:

问题:

页面动画太多会卡顿,出现动画不流畅的问题,并且内存占用率很高。

在使用动画的时候要特别注意动画的回收工作,否则内存会出现占用过高的问题。

给每个view设置动画显然不是很好,数量少可能不明显,如果数量很多就会卡的不动了了。

思路:

将所有的能量球添加统一的一个动画,然后每个能量球的移动距离和速度不同,通过消息去更新所有的能量球位置。

过程:

1.初始化指定数量的能量球(view),并设置一些需要的属性。

private void drawMyCircle() {
        for (int i = 0; i < waterList.size(); i++) {
            View view = mInflater.inflate(R.layout.item_grid_view, this, false);
            TextView textView = view.findViewById(R.id.tv_grid);
            textView.setText(waterList.get(i).value + "g");
            textView.setTag(R.string.value, waterList.get(i));
            textView.setTag(R.string.speed, speList[mRandom.nextInt(speList.length)]);
            textView.setTag(R.string.isUP, mRandom.nextBoolean());
            //设置view位置
            setViewLocation(textView);
            //将初始化好的view添加到容器
            addView(textView);
            //设置点击事件
            textView.setOnClickListener(this);
            waterViewList.add(textView);
        }
        //开始移动容器中所有的能量球了
        mHandler.sendEmptyMessage(1);

    }

这里需要的属性有几种,1.能量球的显示样式,包括大小、颜色、透明度 2.能量球具体在容器中的位置,这也是一个比较重要的点,这里我只是通过随机数来处理的,可以通过算法来尽量保证球的不重合。3.能量球的点击事件。4.保存所有的能量球view

2.能量球放到容器view中,并开始播放动画。

private void setViewOffset() {
        for (int i = 0; i < waterViewList.size(); i++) {
            TextView textView = waterViewList.get(i);
            float y = textView.getY();
            //偏移方向
            Boolean isUP = (Boolean) textView.getTag(R.string.isUP);
            //速度
            float speed = (float) textView.getTag(R.string.speed);
            //原始坐标
            float originalY = (float) textView.getTag(R.string.originalY);
            //移动的坐标
            float translationY;
            if (isUP) {
                translationY = y - speed;
            } else {
                translationY = y + speed;
            }

            if (translationY - originalY > VIEW_OFFSET) {
                translationY = originalY + VIEW_OFFSET;
                textView.setTag(R.string.isUP, true);
            } else if (translationY - originalY < -VIEW_OFFSET) {
                translationY = originalY - VIEW_OFFSET;
                textView.setTag(R.string.isUP, false);
                setSpe(textView);
            }

            textView.setY(translationY);

        }

    }

播放动画需要注意的问题:

首先我们不能使用动画来做,虽然动画写起来比较简单,因为在页面上同时播放过多的动画会导致页面卡顿,内存暴涨(我用动画的方式写了,大约10个球就有点卡了)。

这里选择的是循环去改变每个view的球的y轴上的位置来模拟动画,并且通过handler来循环改变球的位置,消息发送的间隔控制在20毫秒内。测试放过200个球,动画比较平滑。

3.点击能量球后要移除并伴随一个动画。

/**
     * 移除动画
     *
     * @param view
     */
    private void removeViewAnimation(final View view) {
        //清除抖动动画
        view.clearAnimation();
        Interpolator Interpolator = new LinearInterpolator();

        ObjectAnimator transYAnim = ObjectAnimator.ofFloat(view, "translationY", viewHeight - textWidth);
        ObjectAnimator transXAnim = ObjectAnimator.ofFloat(view, "translationX", textWidth);
        ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(view, "scaleX", 1.0f, 0.0f);
        ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(view, "scaleY", 1.0f, 0.0f);
        ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0.0f);

        AnimatorSet set = new AnimatorSet();
        set.setInterpolator(Interpolator);
        set.playTogether(transYAnim, transXAnim, scaleXAnim, scaleYAnim, alphaAnim);
        //不同距离可以设置不同的时间,需要通过移动的距离来计算时间,不过我
        //        int maxLine = viewHeight * viewHeight + viewWidth * viewWidth;
//        int towPointDistance = getTowPointDistance(new Point((int)view.getX(), (int)view.getY()),new Point(0,viewHeight));
//        int time = (int) (Math.sqrt(maxLine) / towPointDistance * 1000);
//        set.setDuration(1000);
        set.setDuration(1000);
        set.start();

        set.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                view.clearAnimation();
                removeView(view);
            }
        });


    }

这里就是简单的使用的属性动画,动画很少写,就算是熟悉了一下。

finish

简单做个记录,不断学习,欢迎指教。

源码点这里,没分的可以留言邮箱

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值