Android使用Circular Reveal動畫讓頁面跳轉(zhuǎn)更炫酷
Android 5.0中引入了很多炫酷的動畫效果,Circular Reveal便是其中一種。使用起來很簡單,但效果卻是意想不到的炫酷,讓你的app更有逼格。
一、效果
廢話不說,下面的gif圖中使用Circular Reveal動畫實現(xiàn)跳轉(zhuǎn)到搜索頁的效果。gif圖壓縮寬高比失真了,不過效果還在。源碼在最下面,可以下載體驗下。

二、Circular Reveal介紹
當(dāng)您顯示或隱藏一組 UI 元素時,揭露動畫可為用戶提供視覺連續(xù)性。
ViewAnimationUtils.createCircularReveal()方法讓您能夠為裁剪區(qū)域添加動畫以揭露或隱藏視圖。
/* @param view The View will be clipped to the animating circle.
* @param centerX The x coordinate of the center of the animating circle, relative to
* <code>view</code>.
* @param centerY The y coordinate of the center of the animating circle, relative to
* <code>view</code>.
* @param startRadius The starting radius of the animating circle.
* @param endRadius The ending radius of the animating circle.
*/
public static Animator createCircularReveal(View view,
int centerX, int centerY, float startRadius, float endRadius) {
return new RevealAnimator(view, centerX, centerY, startRadius, endRadius);
}
ViewAnimationUtils.createCircularReveal()方法所執(zhí)行的效果,就是將一個View裁剪成圓,然后從圓心逐漸揭露展現(xiàn)視圖。
| 參數(shù) | 參數(shù)說明 |
|---|---|
| view | 要執(zhí)行動畫效果的View |
| centerX | 圓心x坐標(biāo) |
| centerY | 圓心y坐標(biāo) |
| startRadius | 開始時的圓半徑 |
| endRadius | 結(jié)束時的圓半徑 |
三、實現(xiàn)

從上圖可以看出,需要揭露展現(xiàn)的View是整個視圖的根布局。開始的位置就是🔍圖標(biāo)的x,y坐標(biāo)。開始的半徑為0,結(jié)束的半徑是上面那條斜邊的長度。知道了這些參數(shù),那么實現(xiàn)就簡單了。
以下代碼使用Kotlin實現(xiàn),不過和java區(qū)別不大,不影響看懂原理。
1.動畫參數(shù)
@SuppressLint("NewApi")
private fun actionOtherVisible(isShow: Boolean, triggerView: View, animView: View) {
//判斷API是否大于21
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
if (isShow) {
animView.visibility = View.VISIBLE
if (mListener != null) mListener!!.onShowAnimationEnd()
} else {
animView.visibility = View.GONE
if (mListener != null) mListener!!.onHideAnimationEnd()
}
return
}
/**
* 計算 triggerView(即搜索按鈕) 的中心位置
*/
val tvLocation = IntArray(2)
triggerView.getLocationInWindow(tvLocation)
val tvX = tvLocation[0] + triggerView.width / 2
val tvY = tvLocation[1] + triggerView.height / 2
/**
* 計算 animView(即根布局) 的中心位置
*/
val avLocation = IntArray(2)
animView.getLocationInWindow(avLocation)
val avX = avLocation[0] + animView.width / 2
val avY = avLocation[1] + animView.height / 2
//計算寬高
val rippleW = if (tvX < avX) animView.width - tvX else tvX - avLocation[0]
val rippleH = if (tvY < avY) animView.height - tvY else tvY - avLocation[1]
//勾股定理求斜邊
val maxRadius = Math.sqrt((rippleW * rippleW + rippleH * rippleH).toDouble()).toFloat()
val startRadius: Float
val endRadius: Float
//根據(jù)展示或隱藏設(shè)置起始與結(jié)束的半徑
if (isShow) {
startRadius = 0f
endRadius = maxRadius
} else {
startRadius = maxRadius
endRadius = 0f
}
val anim = ViewAnimationUtils.createCircularReveal(animView, tvX, tvY, startRadius, endRadius)
animView.visibility = View.VISIBLE
anim.duration = DURATION
anim.interpolator = DecelerateInterpolator()
//監(jiān)聽動畫結(jié)束,進行回調(diào)
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
if (isShow) {
animView.visibility = View.VISIBLE
if (mListener != null) mListener!!.onShowAnimationEnd()
} else {
animView.visibility = View.GONE
if (mListener != null) mListener!!.onHideAnimationEnd()
}
}
})
anim.start()
}
上述代碼中注釋清楚解析了動畫參數(shù)的獲取和執(zhí)行過程。
2.動畫調(diào)用
fun show(triggerView: View, showView: View) {
actionOtherVisible(true, triggerView, showView)
}
fun hide(triggerView: View, hideView: View) {
actionOtherVisible(false, triggerView, hideView)
}
actionOtherVisible()方法根據(jù)傳入true/false來確定是執(zhí)行展示或隱藏動畫。
3.動畫調(diào)用時機
在SearchFragment中,監(jiān)聽第一幀的繪制,開啟動畫。其中mRootView就是根布局View。
override fun onPreDraw(): Boolean {
iv_search_search.viewTreeObserver.removeOnPreDrawListener(this);
mCircularRevealAnim.show(iv_search_search, mRootView);
return true;
}
動畫結(jié)束調(diào)用時機:①在點擊搜索,跳轉(zhuǎn)到搜索結(jié)果界面。②物理回退鍵回退。③點擊回退按鈕
再以上三個地方都可以調(diào)用hide()方法,實現(xiàn)隱藏動畫。
4.監(jiān)聽回調(diào)
在上面配置動畫參數(shù)的過程中,對動畫結(jié)束進行了監(jiān)聽回調(diào)。調(diào)用了AnimListener接口的onHideAnimationEnd()和onShowAnimationEnd()方法,來實現(xiàn)回調(diào)。所有在SearchFragment中實現(xiàn)該接口,來監(jiān)聽回調(diào)。
override fun onHideAnimationEnd() {
et_search_keyword.setText("");
dismiss();
}
override fun onShowAnimationEnd() {
if (isVisible) {
KeyBoardUtils.openKeyboard(activity, et_search_keyword);
}
}
監(jiān)聽到隱藏動畫結(jié)束的時候,調(diào)用dismiss()方法關(guān)閉該DialogFragment。監(jiān)聽展現(xiàn)動畫結(jié)束的時候,開啟輸入法框。
就是這么簡單,通過以上方式就可以實現(xiàn)如此炫酷的效果。
Github地址:搜索頁Circular Reveal動畫
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android Studio實現(xiàn)注冊頁面跳轉(zhuǎn)登錄頁面的創(chuàng)建
- Android實現(xiàn)頁面跳轉(zhuǎn)的全過程記錄
- Android使用Intent顯示實現(xiàn)頁面跳轉(zhuǎn)
- Android使用Intent隱式實現(xiàn)頁面跳轉(zhuǎn)
- Android Intent實現(xiàn)頁面跳轉(zhuǎn)的兩種方法
- Android Intent實現(xiàn)頁面跳轉(zhuǎn)的方法示例
- Android 實現(xiàn)頁面跳轉(zhuǎn)
- Android編程中Intent實現(xiàn)頁面跳轉(zhuǎn)功能詳解
- Android Activity中使用Intent實現(xiàn)頁面跳轉(zhuǎn)與參數(shù)傳遞的方法
- Android實現(xiàn)頁面跳轉(zhuǎn)
相關(guān)文章
Android利用ContentProvider初始化組件的踩坑記錄
做Android SDK開發(fā)的時候,一般我們會將初始化的方法封裝,然后讓調(diào)用SDK的開發(fā)者在Application的onCreate方法中進行初始化,下面這篇文章主要給大家介紹了關(guān)于Android利用ContentProvider初始化組件的踩坑記錄,需要的朋友可以參考下2022-04-04
Android 事件觸發(fā)機制的深入學(xué)習(xí)
這篇文章主要介紹了 Android 事件觸發(fā)機制的深入學(xué)習(xí)的相關(guān)資料,需要的朋友可以參考下2017-06-06
Android改變ExpandableListView的indicator圖標(biāo)實現(xiàn)方法
這篇文章主要介紹了Android改變ExpandableListView的indicator圖標(biāo)實現(xiàn)方法,結(jié)合實例形式分析了改變ExpandableListView的indicator圖標(biāo)相關(guān)步驟與實現(xiàn)技巧,涉及Android配置文件的修改,需要的朋友可以參考下2016-03-03
基于TransactionTooLargeException異常分析
下面小編就為大家分享一篇基于TransactionTooLargeException異常分析,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-11-11
Android App支付系列(二):支付寶SDK接入詳細(xì)指南(附官方支付demo)
本篇文章介紹了Android App支付系列(二):支付寶SDK接入詳細(xì)指南(附官方支付demo) ,有興趣的同學(xué)可以了解一下。2016-11-11

