Android 5.0中引入了很多炫酷的動(dòng)畫效果,Circular Reveal便是其中一種。使用起來很簡單,但效果卻是意想不到的炫酷,讓你的app更有逼格。
英山ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!
一、效果
廢話不說,下面的gif圖中使用Circular Reveal動(dòng)畫實(shí)現(xiàn)跳轉(zhuǎn)到搜索頁的效果。gif圖壓縮寬高比失真了,不過效果還在。源碼在最下面,可以下載體驗(yàn)下。
二、Circular Reveal介紹
當(dāng)您顯示或隱藏一組 UI 元素時(shí),揭露動(dòng)畫可為用戶提供視覺連續(xù)性。
ViewAnimationUtils.createCircularReveal()方法讓您能夠?yàn)椴眉魠^(qū)域添加動(dòng)畫以揭露或隱藏視圖。
/* @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 *view
. * @param centerY The y coordinate of the center of the animating circle, relative to *view
. * @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í)行的效果,就是將一個(gè)View裁剪成圓,然后從圓心逐漸揭露展現(xiàn)視圖。
參數(shù) | 參數(shù)說明 |
---|---|
view | 要執(zhí)行動(dòng)畫效果的View |
centerX | 圓心x坐標(biāo) |
centerY | 圓心y坐標(biāo) |
startRadius | 開始時(shí)的圓半徑 |
endRadius | 結(jié)束時(shí)的圓半徑 |
三、實(shí)現(xiàn)
從上圖可以看出,需要揭露展現(xiàn)的View是整個(gè)視圖的根布局。開始的位置就是🔍圖標(biāo)的x,y坐標(biāo)。開始的半徑為0,結(jié)束的半徑是上面那條斜邊的長度。知道了這些參數(shù),那么實(shí)現(xiàn)就簡單了。
以下代碼使用Kotlin實(shí)現(xiàn),不過和java區(qū)別不大,不影響看懂原理。
1.動(dòng)畫參數(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 } /** * 計(jì)算 triggerView(即搜索按鈕) 的中心位置 */ val tvLocation = IntArray(2) triggerView.getLocationInWindow(tvLocation) val tvX = tvLocation[0] + triggerView.width / 2 val tvY = tvLocation[1] + triggerView.height / 2 /** * 計(jì)算 animView(即根布局) 的中心位置 */ val avLocation = IntArray(2) animView.getLocationInWindow(avLocation) val avX = avLocation[0] + animView.width / 2 val avY = avLocation[1] + animView.height / 2 //計(jì)算寬高 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)聽動(dòng)畫結(jié)束,進(jìn)行回調(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() }
上述代碼中注釋清楚解析了動(dòng)畫參數(shù)的獲取和執(zhí)行過程。
2.動(dòng)畫調(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í)行展示或隱藏動(dòng)畫。
3.動(dòng)畫調(diào)用時(shí)機(jī)
在SearchFragment中,監(jiān)聽第一幀的繪制,開啟動(dòng)畫。其中mRootView就是根布局View。
override fun onPreDraw(): Boolean { iv_search_search.viewTreeObserver.removeOnPreDrawListener(this); mCircularRevealAnim.show(iv_search_search, mRootView); return true; }
動(dòng)畫結(jié)束調(diào)用時(shí)機(jī):①在點(diǎn)擊搜索,跳轉(zhuǎn)到搜索結(jié)果界面。②物理回退鍵回退。③點(diǎn)擊回退按鈕
再以上三個(gè)地方都可以調(diào)用hide()方法,實(shí)現(xiàn)隱藏動(dòng)畫。
4.監(jiān)聽回調(diào)
在上面配置動(dòng)畫參數(shù)的過程中,對動(dòng)畫結(jié)束進(jìn)行了監(jiān)聽回調(diào)。調(diào)用了AnimListener接口的onHideAnimationEnd()和onShowAnimationEnd()方法,來實(shí)現(xiàn)回調(diào)。所有在SearchFragment中實(shí)現(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)聽到隱藏動(dòng)畫結(jié)束的時(shí)候,調(diào)用dismiss()方法關(guān)閉該DialogFragment。監(jiān)聽展現(xiàn)動(dòng)畫結(jié)束的時(shí)候,開啟輸入法框。
就是這么簡單,通過以上方式就可以實(shí)現(xiàn)如此炫酷的效果。
Github地址:搜索頁Circular Reveal動(dòng)畫
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。