以下是部分代碼:
//設置動畫資源
mAnimEnter = AnimationUtils.loadAnimation(this, R.anim.pickerview_slide_in_bottom);
mAnimExit = AnimationUtils.loadAnimation(this, R.anim.pickerview_slide_out_bottom);
//recyclerView 監聽上下滑動的事件
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//處理上下滑動時,顯示和隱藏底部控件,同時漸變狀態欄顏色
handlerRecyclerViewScrollStatus(recyclerView, dx, dy);
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
此處我用的是View動畫,定義的xml資源文件:
view_slide_in_bottom.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:duration="@integer/animation_default_duration"
android:fromXDelta="0%"
android:toXDelta="0%"
android:fromYDelta="200%"
android:toYDelta="0%"/>
</set>
view_slide_out_bottom.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:duration="@integer/animation_default_duration"
android:fromXDelta="0%"
android:toXDelta="0%"
android:fromYDelta="0%"
android:toYDelta="200%"/>
</set>
需要注意的是toYDelta設置成100%一般是不滿足的,因爲Button需要設置padding和margin值的.
然後是具體實現滑動的事件的的代碼
private void handlerRecyclerViewScrollStatus(RecyclerView recyclerView, int dx, int dy) {
//根據滑動方向去設置不同的事件
if (dy > 0 ) {
if (recyclerView.getScrollState() == ScrollState.SCROLL_STATE_SETTLING) { //設置此處的目的的爲了防止拖拽中的抖動
setBtAnimExit();
}
} else {
if (recyclerView.getScrollState() == ScrollState.SCROLL_STATE_SETTLING) {//設置此處的目的的爲了防止拖拽中的抖動
setBtAnimEnter();
}
int scrollY = getScollYDistance() - 60;//根據滑動距離去計算透明度
float alpha = scrollY * 1.0f / 500;
//nVewTitleBg是標題欄的文字
nViewTitleBg.setAlpha(alpha); //設置標題欄文字的透明度,產生漸變效果
//nStatusBarLine是標題欄的背景
if (nStatusBarLine != null) {
nStatusBarLine.setAlpha(alpha);//設置標題欄背景的透明度,產生漸變效果
}
}
Timber.tag("anim");
Timber.e("dy=" + dy + ", getScollYDistance()=" + getScollYDistance() + ",...ScrollState" + recyclerView.getScrollState());
}
關於這裏的判斷是必須的,不然手指一直拖拽的話,動畫會不停的一直重複執行,一些app 沒有處理這裏.當然這樣的處理也是有問題的,因爲除非用戶1秒內不停的小動作滑動,底部的控件無法顯示,但是在實際環境中是很少存在的.
如果不去設置的話,會導致,1秒內小範圍滑動,動畫會多次重複啓動.
recyclerView.getScrollState() == ScrollState.SCROLL_STATE_SETTLING
然後是設置動畫的代碼:
private void setBtAnimExit() {
if (mBt.getVisibility() == View.GONE) { //防止重複執行
return;
}
mAnimExit.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mBt.setVisibility(View.GONE); //執行以後,就隱藏,如果滑動的距離不夠的話,會導致無法隱藏掉控件,所以這裏手動設置
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
mBt.startAnimation(mAnimExit);
}
private void setBtAnimEnter() {
if (mBt.getVisibility() == View.VISIBLE) {
return;
}
mAnimEnter.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mBt.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
mBt.startAnimation(mAnimEnter);
}
以上可以用屬性動畫去設置,遇到的坑應該會更少,因爲屬性動畫是真實的將控件的內容給平移到指定位置了
最後別忘記釋放資源,看情況是在onPause還是onDestroy裏面去釋放.最好即時釋放,因爲android系統執行釋放的時機一般比較晚.
@Override
protected void onDestroy() {
super.onDestroy();
if (mAnimEnter != null) {
mAnimEnter.cancel();
mAnimEnter = null;
}
if (mAnimExit != null) {
mAnimExit.cancel();
mAnimExit = null;
}
最後是資源文件:
資源文件動畫的調用
屬性動畫
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
R.anim.property_animator);
set.setTarget(myObject);
set.start();
View動畫
ImageView image = (ImageView) findViewById(R.id.image);
Animation hyperspaceJump = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
image.startAnimation(hyperspaceJump);
幀動畫 XML
幀動畫的文件是存儲在drawble文件當中的,此處實例放在R.drawable.rocket_thrust中:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
<item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
<item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>
代碼中調用
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
rocketAnimation.start();
此處是動畫的文檔: https://developer.android.google.cn/guide/