使用Circular Reveal動(dòng)畫讓頁面跳轉(zhuǎn)更炫酷

Android 5.0中引入了很多炫酷的動(dòng)畫效果疾层,Circular Reveal便是其中一種。使用起來很簡單卵史,但效果卻是意想不到的炫酷战转,讓你的app更有逼格。

一以躯、效果

廢話不說槐秧,下面的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
     *                <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í)行的效果,就是將一個(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)畫

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末墩崩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子侯勉,更是在濱河造成了極大的恐慌鹦筹,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件址貌,死亡現(xiàn)場離奇詭異铐拐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)练对,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門遍蟋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人螟凭,你說我怎么就攤上這事虚青。” “怎么了螺男?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵挟憔,是天一觀的道長钟些。 經(jīng)常有香客問我烟号,道長绊谭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任汪拥,我火速辦了婚禮达传,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘迫筑。我一直安慰自己宪赶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布脯燃。 她就那樣靜靜地躺著搂妻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辕棚。 梳的紋絲不亂的頭發(fā)上欲主,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機(jī)與錄音逝嚎,去河邊找鬼扁瓢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛补君,可吹牛的內(nèi)容都是我干的引几。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼挽铁,長吁一口氣:“原來是場噩夢啊……” “哼伟桅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叽掘,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤楣铁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后够掠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體民褂,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年疯潭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赊堪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡竖哩,死狀恐怖哭廉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情相叁,我是刑警寧澤遵绰,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布辽幌,位于F島的核電站,受9級特大地震影響椿访,放射性物質(zhì)發(fā)生泄漏乌企。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一成玫、第九天 我趴在偏房一處隱蔽的房頂上張望加酵。 院中可真熱鬧,春花似錦哭当、人聲如沸猪腕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽陋葡。三九已至,卻和暖如春彻采,著一層夾襖步出監(jiān)牢的瞬間腐缤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工颊亮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柴梆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓终惑,卻偏偏與公主長得像绍在,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子雹有,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫偿渡、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,103評論 4 62
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,118評論 25 707
  • 學(xué)校舉辦了一個(gè)活動(dòng)霸奕,給父母做一餐美食溜宽,作為六一節(jié)反饋給父母的一種感恩。兒子接到老師的通知后躍躍欲試质帅,對我說:媽...
    鄧啟旭鄧君浩媽媽閱讀 270評論 0 1
  • 大家好,我是靈犬零零一魄揉,我是五只靈犬宣傳委員會(huì)的一員剪侮。今天五只靈犬終于逆襲成功啦,為了拿獎(jiǎng)還真是“不擇手段了呢”洛退。...
    思敏_e2ec閱讀 175評論 0 0
  • 藝術(shù)無國界瓣俯,藝術(shù)品有杰标;音樂無國界,音樂家有彩匕;文學(xué)無國界腔剂,文學(xué)家有……所以,世界公民的定義永遠(yuǎn)行不通推掸,天下大同的想法...
    24e2f6668318閱讀 284評論 0 0