使用動(dòng)畫(huà)隱藏或顯示View

一般來(lái)說(shuō),當(dāng)內(nèi)容更換時(shí),有動(dòng)畫(huà)的話會(huì)更好過(guò)渡,用戶也會(huì)體驗(yàn)較好。有三種比較常見(jiàn)的動(dòng)畫(huà)用于隱藏或顯示內(nèi)容:Circle Reveal動(dòng)畫(huà)、淡入淡出效果、卡片翻轉(zhuǎn)效果。

下面將分別介紹這三種常見(jiàn)的動(dòng)畫(huà)效果:

淡入淡出動(dòng)畫(huà)

淡入淡出動(dòng)畫(huà)一般是一個(gè)View在漸漸消失,另一個(gè)View同時(shí)在漸漸出現(xiàn)。

先看效果,如下圖:

淡入淡出效果動(dòng)畫(huà)

可以看到效果是一個(gè)文本漸漸出現(xiàn),loading漸漸消失。

創(chuàng)建xml布局

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".animation.CrossFadeActivity">

    <ScrollView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            style="?android:textAppearanceMedium"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:lineSpacingMultiplier="1.2"
            android:padding="16dp"
            android:text="@string/large_text"/>

    </ScrollView>

    <ProgressBar
        android:id="@+id/loading_spinner"
        style="?android:progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/>
</FrameLayout>

代碼實(shí)現(xiàn)動(dòng)畫(huà)

class CrossFadeActivity : AppCompatActivity() {

    private var mShortAnimationDuration: Int = 5000

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_cross_fade)
        crossFade()
    }

    private fun crossFade() {
        content.apply {
            visibility = View.VISIBLE
            alpha = 0f

            animate().alpha(1.0f)
                    .setDuration(mShortAnimationDuration.toLong())
                    .withEndAction {
                        content.visibility = View.VISIBLE
                    }.start()

        }

        loading_spinner.animate()
                .alpha(0.0f)
                .setDuration(mShortAnimationDuration.toLong())
                .withEndAction {
                    loading_spinner.visibility = View.GONE
                }.start()

    }

}

這里使用的屬性動(dòng)畫(huà),初始時(shí)內(nèi)容alpha=0,漸漸變?yōu)?,而loading的alpha則由1變?yōu)?。喂了看出效果因此,設(shè)置了5s。

卡片翻轉(zhuǎn)動(dòng)畫(huà)

先看效果:

卡片翻轉(zhuǎn)動(dòng)畫(huà)效果

這里采用自定義Fragment的專場(chǎng)動(dòng)畫(huà),其中有兩個(gè)Fragment,布局都很簡(jiǎn)單,就不展示了。

動(dòng)畫(huà)代碼

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Before rotating, immediately set the alpha to 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:duration="0" />

    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="180"
        android:valueTo="0"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="@integer/card_flip_time_half" />
</set>

其他類似,分別表示左進(jìn)、左出、右進(jìn)、右出的動(dòng)畫(huà)。

Kotlin代碼

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_card_flip)
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                    .add(R.id.container, CardFrontFragment())
                    .commit()
        }
    }

    override fun onBackPressed() {
        flipCard()
    }

    private var mShowingBack: Boolean = false

    private fun flipCard() {
        if (mShowingBack) {
            supportFragmentManager.popBackStack()
            mShowingBack = false
            return
        }

        mShowingBack = true

        supportFragmentManager.beginTransaction()
                .setCustomAnimations(
                        R.animator.card_flip_right_in,
                        R.animator.card_flip_right_out,
                        R.animator.card_flip_left_in,
                        R.animator.card_flip_left_out
                )
                .replace(R.id.container, CardBackFragment())
                .addToBackStack(null)
                .commit()
    }

重寫(xiě)了返回鍵,就是為了看效果。

去掉自定義的動(dòng)畫(huà),轉(zhuǎn)場(chǎng)如下圖所示:

Fragment默認(rèn)的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)

是不是很突兀?看來(lái)有個(gè)動(dòng)畫(huà)還是真的不一樣的。

Circle Reveal動(dòng)畫(huà)

話不多說(shuō),先看效果:

Circle Reveal動(dòng)畫(huà)效果

ViewAnimationUtils.createCircularReveal()方法使我們可以有上述的效果。但是該類在API 21之上才有效果。

顯示代碼

顯示代碼如下:

private fun showView() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val cx = text.width / 2
            val cy = text.height / 2

            val finalRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()
            val anim = ViewAnimationUtils.createCircularReveal(text, cx, cy, 0f, finalRadius)
            text.visibility = View.VISIBLE
            anim.start()
        } else {
            text.visibility = View.VISIBLE
        }
    }

隱藏代碼

private fun hideView() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val cx = text.width / 2
            val cy = text.height / 2

            val initRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()
            val anim = ViewAnimationUtils.createCircularReveal(text, cx, cy, initRadius, 0f)
            anim.addListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator?) {
                    super.onAnimationEnd(animation)
                    text.visibility = View.INVISIBLE
                }
            })
            anim.start()
        } else {
            text.visibility = View.INVISIBLE
        }
    }

總結(jié)

動(dòng)畫(huà)確實(shí)很炫酷,不過(guò)要慎用,這周開(kāi)發(fā)就遇到了坑,有機(jī)會(huì)會(huì)以文章的形式記錄下來(lái)。

關(guān)于代碼,請(qǐng)見(jiàn) Github

參考:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 永遠(yuǎn)是悲傷的 永遠(yuǎn)是憂郁的 那野地上的花 樹(shù)枝上的鳥(niǎo) 選山處的烏鴉 是自由 是歌唱著的 不知疲倦的歌謠 天空柔...
    蘇小素閱讀 266評(píng)論 5 7
  • 育人寶貝教師百日行動(dòng)派#day37 每日5000步?? 今日所讀《3~6歲兒童學(xué)習(xí)與發(fā)展指南》 傾聽(tīng)與表達(dá) 多給幼...
    大慧_adaa閱讀 227評(píng)論 0 0
  • 推遲滿足感! 集中精力先辦復(fù)雜的難事,大事,再次,處理得心應(yīng)手的,過(guò)程與體驗(yàn)慢慢會(huì)輕松許多。改變問(wèn)題結(jié)構(gòu),從努力克...
    超少閱讀 133評(píng)論 0 4
  • 抖音火了這么久,但實(shí)際上自己從來(lái)沒(méi)下載過(guò),也從來(lái)沒(méi)去看過(guò)。前兩天因?yàn)榇蛩阌枚兑糇鲂∫曨l所以就下載去研究一下。 利用...
    貓女杜瑜閱讀 3,578評(píng)論 0 1
  • 看到竹海首先被驚到的是那氣勢(shì):翠浪當(dāng)空,無(wú)休無(wú)止。風(fēng),引誘著竹,吸引著竹,一撥又一撥,一陣又一陣,不斷向前...
    冰夫閱讀 334評(píng)論 0 0

友情鏈接更多精彩內(nèi)容