標籤: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,歡迎查看!
有任何疑問或者探討了,歡迎留言或者聯絡我
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Android開發:帶動畫的分享效果