写在前面的话
【Android开发|Android中ValueAnimator的使用】这个时代,新物种正在生长,新边疆正在延伸。做别人的小兵,还是做自己的将军,你选。前言
效果图
- 今天给大家带来的是ValueAnimator的相关用法,下面先给大家看下效果图。
动画介绍
这里我们写了两个位移动画,分别是城市交换动画和日期位移动画,下面我们将通过代码详细介绍下两个动画的具体实现,从而理解valueAnimator的相关使用。城市交换动画
- 左边城市:startCityTextView
- 右边城市:endCityTextView
- 首先获取startCityTextView和endCityTextView的x坐标,因为是水平方向的移动。
- startX:左边城市的横坐标
- endX:右边城市的横坐标
private int startX;
private int endX;
private void getLocation() {
int[] startLocation = new int[2];
startCityTextView.getLocationOnScreen(startLocation);
int[] endLocation = new int[2];
endCityTextView.getLocationOnScreen(endLocation);
startX = startLocation[0];
endX = endLocation[0];
}
左边城市动画
- 移动距离
final int moveX = endX - startX + endCityTextView.getWidth() - startCityTextView.getWidth();
- 动画代码
ValueAnimator startCityAnimation = ValueAnimator.ofInt(0, moveX).setDuration(500);
startCityAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = https://www.it610.com/article/(int) animation.getAnimatedValue();
startCityTextView.layout(startX + value, startCityTextView.getTop(), startX + value + startCityTextView.getWidth(), startCityTextView.getBottom());
}
});
startCityAnimation.start();
右边城市动画
- 移动距离
int rightMoveX = endX - startX;
- 动画代码
ValueAnimator endCityAnimator = ValueAnimator.ofInt(0, rightMoveX).setDuration(500);
endCityAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = https://www.it610.com/article/(int) animation.getAnimatedValue();
endCityTextView.layout(endX - value, endCityTextView.getTop(), endX + endCityTextView.getWidth() - value, endCityTextView.getBottom());
}
});
endCityAnimator.start();
调换view位置
最后需要在动画结束后调换view的位置, 使startCityTextView变为endCityTextView,这样下次动画执行时位置坐标才正确。
endCityAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}@Override
public void onAnimationEnd(Animator animation) {
TextView flagTextView = startCityTextView;
startCityTextView = endCityTextView;
endCityTextView = flagTextView;
}@Override
public void onAnimationCancel(Animator animation) {
}@Override
public void onAnimationRepeat(Animator animation) {
}
});
日期位移动画
透明度动画
- isSingleLine:判断是点击的单程还是往返
- 单程:透明度由1变到0,通过重写ObjectAnimator的setEvaluator方法,其中fraction的变化是由0到1
- 往返:透明度从0变到1
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(rightLayout, View.ALPHA, 0, 1.0f).setDuration(1000);
if (isSingleLine) {
alphaAnimator.setEvaluator(new TypeEvaluator() {
@Override
public Float evaluate(float fraction, Float startValue, Float endValue) {
return 1 - fraction;
}
});
}
alphaAnimator.start();
位移动画
动画分析:
- screenWidth 屏幕宽度
- 往返:把view从screenWidth+view.getWidth()的位置移动到screenWidth-view.getWidth的位置,移动距离:view.getWidth()
- 单程:把view移出到screenWidth和view.getWidth()之和的位置,移动距离:view.getWidth()
- 获取屏幕宽度
private int getScreenWidth() {
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
return displayMetrics.widthPixels;
}
- 动画代码
ValueAnimator animator = ValueAnimator.ofFloat(0, rightLayout.getWidth()).setDuration(500);
animator.setEvaluator(isSingleLine ? new ATFlightEvaluator() : new FloatEvaluator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = https://www.it610.com/article/(float) animation.getAnimatedValue();
int screenWidth = getScreenWidth();
rightLayout.layout(screenWidth - (int) value, rightLayout.getTop(), screenWidth + rightLayout.getWidth() - (int) value, rightLayout.getBottom());
}
});
animator.start();
- ATFlightEvalutor
这里isSingleLine时我们设置其Evaluator为我们自定义的ATFlightEvalutor,实现TypeEvaluator接口并重写其evaluate方法,这样我们获取到动画变化中的value值就是由view.getWidth()—>0变化的。
- startValue: 0
- endValue: view.getWidth()
- fraction: 动画的变化率0—>1
- 其最后返回的值就是我们使用animation.getAnimatedValue()获取的值。
public class ATFlightEvaluator implements TypeEvaluator {@Override
public Float evaluate(float fraction, Float startValue, Float endValue) {
return endValue - fraction * (endValue - startValue);
}
}
总结
以上就是我们通过valueAnimator实现的两个小实例,有兴趣的童鞋可以研究下代码,另外有不明白的地方可以在下面留言或者发邮件kuangxiaoguo@163.com。
推荐阅读
- 从零开发一个完整的Android项目(九)——图片浏览
- Android开发|ViewPager自适应高度问题
- Android|Android 指定销毁一个Activity
- 【Android】简单图片浏览器
- 理解ButterKnife(自动生成绑定资源的代码)
- MAC下搭建Android Studio
- NestedScrollingParent 和NestedScrollingChild 实现嵌套滑动
- android用shape画一条横线
- 华为推送 的坑
- Duplicate class com.alipay.a.a.a found in modules classes.jar (:alipaySdk-15.6.2-20190416165036:) an