前言
通過上一篇Android 屬性動畫拓展(一),我們已經(jīng)對知道,通過改變View的屬性值蜡娶,可以實(shí)現(xiàn)動畫效果;當(dāng)然映穗,上一篇的ViewPager比較特殊窖张,通過他的setPageTransformer方法可以很方便的為他添加動畫效果。那么對于普通的View蚁滋,我們?nèi)绾谓Y(jié)合用戶的操作(主要是滑動)實(shí)現(xiàn)一些動畫呢宿接?下面我們就來看看。
標(biāo)題欄漸變效果
標(biāo)題欄顏色漸變的效果辕录,想必大家都不陌生睦霎。
上面這樣一個效果實(shí)現(xiàn),主要思路還是通過計(jì)算上下滑動的比例走诞,動態(tài)的修改頂部View的背景色副女。
//定義動畫初始顏色和最終顏色值
mColorAnimator = new ColorAnimator(Color.TRANSPARENT, getResources().getColor(R.color.colorPrimaryDark));
mNestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, final int scrollY, int oldScrollX, int oldScrollY) {
float fraction = (float) scrollY / (mViewPager.getHeight());
int color = mColorAnimator.getFractionColor(fraction);
if (color != lastColor) {
lastColor = color;
head.setBackgroundColor(color);
StatusBarUtil.setColor(IModeActivity.this, color, 0);
}
if (fraction < 1) {
title.setVisibility(View.INVISIBLE);
search.setVisibility(View.INVISIBLE);
} else {
title.setVisibility(View.VISIBLE);
search.setVisibility(View.VISIBLE);
}
}
});
這里使用NestedScrollView,可以直接監(jiān)聽滑動的距離蚣旱。
在代碼中碑幅,我們用當(dāng)前滑動的距離/頂部ViewPager的高度,得出一個比例fraction塞绿,當(dāng)我們滑動的距離大于等于ViewPager高度時(shí)沟涨,fraction=1,此時(shí)整個head 將會完全顯示為最終的顏色异吻。
同時(shí)使用StatusBarUtil動態(tài)修改狀態(tài)欄的背景色裹赴,保持整個視圖的一致。
看到fraction這個參數(shù)你應(yīng)該不陌生,之前學(xué)習(xí)屬性動畫實(shí)現(xiàn)機(jī)制的時(shí)候我們知道了篮昧。
public class PointSinEvaluator implements TypeEvaluator {
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
Point startPoint = (Point) startValue;
Point endPoint = (Point) endValue;
float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());
float y = (float) (Math.sin(x * Math.PI / 180) * 100) + endPoint.getY() / 2;
Point point = new Point(x, y);
return point;
}
}
我們知道TypeEvaluator 決定了動畫的執(zhí)行的變化過程赋荆,這里的fraction參數(shù)值是由動畫的Interpolator決定的。因此懊昨,在之前的屬性動畫中窄潭,系統(tǒng)會根據(jù)我們的代碼,自動計(jì)算fraction值酵颁,自動的完成整個動畫嫉你。而這里,我們的工作就是根據(jù)UI交互的效果躏惋,手動的去算整個值幽污,主動的決定了動畫變化的過程。也就是這里標(biāo)題欄背景色變化的過程簿姨。
ColorAnimator其實(shí)就是一個顏色變化的差值器距误,其內(nèi)部實(shí)現(xiàn)了隨著參數(shù)的變化,起始顏色的漸變過渡效果扁位,這樣可以保證顏色過渡有層次感准潭,而不是在兩種不同的顏色之前很突兀的切換。
仿簡書頭部效果
簡書APP發(fā)現(xiàn)頁面域仇,頭部也是一個由透明色變化為白色的標(biāo)題欄刑然,標(biāo)題欄內(nèi)部的搜索框也會動態(tài)擴(kuò)展,結(jié)合上面的例子可以考慮一下如何實(shí)現(xiàn)暇务;首先看一下效果泼掠。
結(jié)合上面的例子,實(shí)現(xiàn)頂部search框背景由透明變?yōu)榘咨严福呛苋菀椎膶?shí)現(xiàn)的择镇。搜索框 伸縮變化也是很簡單,整個view的寬度動態(tài)變化即可括改。
final ColorAnimator mColorAnimator = new ColorAnimator(Color.TRANSPARENT, Color.WHITE);
mNestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
float fraction = (float) 2 * scrollY / (mImage.getHeight());
int color = mColorAnimator.getFractionColor(fraction);
if (color != lastColor) {
lastColor = color;
mHead.setBackgroundColor(color);
// StatusBarUtil.setColor(JianShuHeadActivity.this, color, 0);
}
Log.e(TAG, "onScrollChange: fraction=" + fraction);
if (fraction >= 0.7f) {
mSearchTv.setText("搜索簡書的內(nèi)容和朋友");
ViewGroup.LayoutParams mParams = mSearchShell.getLayoutParams();
mParams.width = RecyclerView.LayoutParams.MATCH_PARENT;
mSearchShell.setLayoutParams(mParams);
TransitionManager.beginDelayedTransition(mSearchShell);
}
if (fraction <= 0.3f) {
mSearchTv.setText("搜索");
ViewGroup.LayoutParams mParams = mSearchShell.getLayoutParams();
mParams.width = RecyclerView.LayoutParams.WRAP_CONTENT;
mSearchShell.setLayoutParams(mParams);
TransitionManager.beginDelayedTransition(mSearchShell);
}
}
});
代碼內(nèi)容很容易理解沐鼠,由于在布局文件中已經(jīng)為mSearchShell在左右兩邊保留了相等且足夠的外邊距值,因此隨著滑動系數(shù)簡單的修改一下其寬度即可叹谁,最后在加一個transaction的動畫可以使變化顯得比較柔和饲梭。
按照上面的內(nèi)容,其實(shí)和簡書實(shí)際的效果是有一些差距的焰檩,可以看到我們注釋掉了修改狀態(tài)欄背景色的代碼憔涉;原因很明顯,Android系統(tǒng)默認(rèn)的狀態(tài)欄字體是白色的析苫,因此當(dāng)我們把狀態(tài)欄背景色變成白色時(shí)兜叨,整個視圖效果將會非常難看穿扳。
在部分小米手機(jī)上,可以通過反射的方式將字體改為黑色国旷,但是大部分手機(jī)狀態(tài)欄的字體好像還不能動態(tài)修改矛物。因此,我們會發(fā)現(xiàn)跪但,有時(shí)候最不起眼的內(nèi)容履羞,反而是最難實(shí)現(xiàn)的。
小結(jié)
這篇主要就上下滑動時(shí)的效果屡久,結(jié)合時(shí)下開發(fā)中常用到的一個點(diǎn)做了簡單的分析忆首,下一篇我們結(jié)合左右滑動的效果看看,利用屬性動畫我們能玩出什么花樣被环。
最后糙及,差點(diǎn)忘了,文中所有源碼地址AndroidAnimationExercise筛欢。有興趣的同學(xué)歡迎star & fork浸锨。