zoukankan      html  css  js  c++  java
  • Android开发:带动画的分享效果

    这几天做了个带动画的分享页面。如今把它分享出来,假设你认为实用,请直接使用,避免反复造轮子

    先看下效果图
    这里写图片描写叙述

    认为仅仅是看效果图不明显。那么用手机扫描以下的二维码下载安装包:

    这里写图片描写叙述

    这个效果本身没有什么特别的难度,都是用Animator实现的,仅仅是动画效果的代码量有点多。由于分享模块一般都会做,把这个分享出来,想要用的话,就不要反复写这么多行代码了

    对于熟悉Animator的人。以下的代码能够略过了

    我来看下基本的实现代码,完整的代码看底部的项目Github地址

    1. 我用了一个方法。实现进入的效果,加上判定,是否须要隐藏二维码页面

    private void moveInAnim(boolean isHideCode) {
            ObjectAnimator friendAnimatorX = ObjectAnimator.ofFloat(tvFriend, "TranslationX", 0);
            ObjectAnimator friendAnimatorY = ObjectAnimator.ofFloat(tvFriend, "TranslationY", 0);
            ObjectAnimator timelineAnimatorX = ObjectAnimator.ofFloat(tvTimeline, "TranslationX", 0);
            ObjectAnimator timelineAnimatorY = ObjectAnimator.ofFloat(tvTimeline, "TranslationY", 0);
            ObjectAnimator qrcodeAnimatorX = ObjectAnimator.ofFloat(tvQrcode, "TranslationX", 0);
            ObjectAnimator qrcodeAnimatorY = ObjectAnimator.ofFloat(tvQrcode, "TranslationY", 0);
            ObjectAnimator copyAnimatorX = ObjectAnimator.ofFloat(tvCopylink, "TranslationX", 0);
            ObjectAnimator copyAnimatorY = ObjectAnimator.ofFloat(tvCopylink, "TranslationY", 0);
    
            AnimatorSet set = new AnimatorSet();
            set.setDuration(ANIM_TIME);
    
            if (isHideCode) {
                ObjectAnimator animatorX = ObjectAnimator.ofFloat(tvCode, "ScaleX", 0.1f);
                ObjectAnimator animatorY = ObjectAnimator.ofFloat(tvCode, "ScaleY", 0.1f);
                set.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        tvCode.setVisibility(View.INVISIBLE);
                    }
                });
                set.playTogether(friendAnimatorX, friendAnimatorY, timelineAnimatorX, timelineAnimatorY
                        , qrcodeAnimatorX, qrcodeAnimatorY, copyAnimatorX, copyAnimatorY, animatorX, animatorY);
            } else {
                set.setInterpolator(new FastOutSlowInInterpolator());
                set.playTogether(friendAnimatorX, friendAnimatorY, timelineAnimatorX, timelineAnimatorY
                        , qrcodeAnimatorX, qrcodeAnimatorY, copyAnimatorX, copyAnimatorY);
            }
    
            set.start();
        }

    在Animator中实现x轴跟Y轴,还有缩放的效果。有心人可能会发现,为什么我移动的參数都是0f呢,那么起始的值跑到哪里去了,请接着看第二点。

    2. 初始化位置

    tvFriend.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    tvFriend.getViewTreeObserver().removeOnPreDrawListener(this);
                    tvFriend.setTranslationX(-screenWidth / 2);
                    tvFriend.setTranslationY(-tvFriend.getHeight() * 2);
                    return false;
                }
            });
            tvTimeline.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    tvTimeline.getViewTreeObserver().removeOnPreDrawListener(this);
                    tvTimeline.setTranslationX(screenWidth / 2);
                    tvTimeline.setTranslationY(-tvFriend.getHeight() * 2);
                    return false;
                }
            });
            tvQrcode.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    tvQrcode.getViewTreeObserver().removeOnPreDrawListener(this);
                    tvQrcode.setTranslationX(-screenWidth / 2);
                    tvQrcode.setTranslationY(tvFriend.getHeight() * 2);
                    return false;
                }
            });
            tvCopylink.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    tvCopylink.getViewTreeObserver().removeOnPreDrawListener(this);
                    tvCopylink.setTranslationX(screenWidth / 2);
                    tvCopylink.setTranslationY(tvFriend.getHeight() * 2);
                    return false;
                }
            });

    初始化位置的方法,要放在addOnPreDrawListener中,这就是为什么在上一点中,仅仅要把值设成0f就能够的原因

    3. 移动出去的动画

    private void moveOutAnim(boolean isFinishActivity, boolean isShowCode) {
            ObjectAnimator friendAnimatorX = ObjectAnimator.ofFloat(tvFriend, "TranslationX", -screenWidth / 2);
            ObjectAnimator friendAnimatorY = ObjectAnimator.ofFloat(tvFriend, "TranslationY", -tvFriend.getHeight() * 2);
            ObjectAnimator timelineAnimatorX = ObjectAnimator.ofFloat(tvTimeline, "TranslationX", screenWidth / 2);
            ObjectAnimator timelineAnimatorY = ObjectAnimator.ofFloat(tvTimeline, "TranslationY", -tvFriend.getHeight() * 2);
            ObjectAnimator qrcodeAnimatorX = ObjectAnimator.ofFloat(tvQrcode, "TranslationX", -screenWidth / 2);
            ObjectAnimator qrcodeAnimatorY = ObjectAnimator.ofFloat(tvQrcode, "TranslationY", tvFriend.getHeight() * 2);
            ObjectAnimator copyAnimatorX = ObjectAnimator.ofFloat(tvCopylink, "TranslationX", screenWidth / 2);
            ObjectAnimator copyAnimatorY = ObjectAnimator.ofFloat(tvCopylink, "TranslationY", tvFriend.getHeight() * 2);
    
            AnimatorSet set = new AnimatorSet();
            set.setDuration(ANIM_TIME);
    
            if (isShowCode) {
                addQrcode();
                ObjectAnimator animatorScaleX = ObjectAnimator.ofFloat(tvCode, "ScaleX", 1f);
                ObjectAnimator animatorScaleY = ObjectAnimator.ofFloat(tvCode, "ScaleY", 1f);
                animatorScaleX.setInterpolator(overshootInterpolator);
                animatorScaleY.setInterpolator(overshootInterpolator);
                set.playTogether(friendAnimatorX, friendAnimatorY, timelineAnimatorX, timelineAnimatorY
                        , qrcodeAnimatorX, qrcodeAnimatorY, copyAnimatorX, copyAnimatorY, animatorScaleX, animatorScaleY);
            } else {
                set.playTogether(friendAnimatorX, friendAnimatorY, timelineAnimatorX, timelineAnimatorY
                        , qrcodeAnimatorX, qrcodeAnimatorY, copyAnimatorX, copyAnimatorY);
            }
    
            if (isFinishActivity) {
                set.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        finish();
                        overridePendingTransition(0, 0);
                    }
                });
            }
    
            set.start();
        }
    

    跟移动进来的动画大同小异,我就不复述了

    4. 刚開始打开页面的时候,启动动画的方法:

    tvFriend.post(new Runnable() {
                @Override
                public void run() {
                    moveInAnim(false);
                }
            });

    用post的方法,能够非常好的实现一開始的动画,假设直接在onResume中调用,或者其它的地方调用。就会出现卡顿,至于为什么这种方法能够。或者说有没有更好的的方法,希望有熟悉handle之类的人来解释下,感谢了

    5. 注意的地方
    有些手机会有默认的页面切换动画,比方我的M2手机就是向左滑动。退出就是向右滑动,为了避免有些手机的默认动画,能够在启动页面和退出页面的代码后面,加上例如以下的代码,避免出现默认的切换效果

    overridePendingTransition(0, 0);

    项目的源码我放到了Github。欢迎查看!

    有不论什么疑问或者探讨了,欢迎留言或者联系我

  • 相关阅读:
    CentOS安装使用.netcore极简教程(免费提供学习服务器)
    新生命团队netcore服务器免费开放计划
    线程池ThreadPool及Task调度死锁分析
    NetCore版RPC框架NewLife.ApiServer
    NewLife.Net——管道处理器解决粘包
    NewLife.Net——网络压测单机2266万tps
    NewLife.Net——构建可靠的网络服务
    NewLife.Net——开始网络编程
    搬家
    借助Redis做秒杀和限流的思考
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7358188.html
Copyright © 2011-2022 走看看