一般來說漱凝,當(dāng)內(nèi)容更換時,有動畫的話會更好過渡惰瓜,用戶也會體驗較好否副。有三種比較常見的動畫用于隱藏或顯示內(nèi)容:Circle Reveal動畫、淡入淡出效果崎坊、卡片翻轉(zhuǎn)效果备禀。
下面將分別介紹這三種常見的動畫效果:
淡入淡出動畫
淡入淡出動畫一般是一個View在漸漸消失,另一個View同時在漸漸出現(xiàn)。
先看效果曲尸,如下圖:
淡入淡出效果動畫
可以看到效果是一個文本漸漸出現(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>
代碼實現(xiàn)動畫
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()
}
}
這里使用的屬性動畫另患,初始時內(nèi)容alpha=0纽乱,漸漸變?yōu)?,而loading的alpha則由1變?yōu)?昆箕。喂了看出效果因此鸦列,設(shè)置了5s。
卡片翻轉(zhuǎn)動畫
先看效果:
卡片翻轉(zhuǎn)動畫效果
這里采用自定義Fragment的專場動畫鹏倘,其中有兩個Fragment薯嗤,布局都很簡單,就不展示了第股。
動畫代碼
<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)诲锹、右出的動畫。
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()
}
重寫了返回鍵涉馅,就是為了看效果归园。
去掉自定義的動畫,轉(zhuǎn)場如下圖所示:
Fragment默認(rèn)的轉(zhuǎn)場動畫
是不是很突兀稚矿?看來有個動畫還是真的不一樣的庸诱。
Circle Reveal動畫
話不多說,先看效果:
Circle Reveal動畫效果
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é)
動畫確實很炫酷,不過要慎用昧识,這周開發(fā)就遇到了坑钠四,有機(jī)會會以文章的形式記錄下來。
關(guān)于代碼跪楞,請見 Github
參考: