以下是部分代码:
//设置动画资源
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
view_slide_out_bottom.xml
需要注意的是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中:
"1.0" encoding="utf-8"?>
android:oneshot="false">
代码中调用
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/