TypeEvaluator 估值器 抛物线
2024-08-25 07:00:48
TypeEvaluator简介
Android提供了以下几个简单的Evalutor实现类:
- IntEvaluator:属性的值类型为int
- FloatEvaluator:属性的值类型为float
- ArgbEvaluator:属性的值类型为十六进制颜色值
TypeEvaluator:一个接口,可以通过实现该接口自定义Evaluator。
TypeEvaluator的实现过程:
首先根据动画【已进行的时间】跟动画【总时间】的比计算出一个时间因子(0~1,即evalute()中的fraction参数,这个值是自动计算得到的)
然后根据【TimeInterpolator】得到出另一个算法因子
TypeEvaluator通过这【两个】因子计算出属性值并将其【传给】我们定义的泛型对象
最后在我们监听动画的绘制过程中,将泛型对象中保存的值【取出】并用于【更改】目标对象的属性
自定义TypeEvaluator时传入的泛型可以根据自己的需求,自己设计个Bean。
只要evaluate中的函数能够满足:当fraction=0时返回值为startValue,并且当fraction=1时返回值为endValue,就是一个比较合理的函数。
TypeEvaluator 接口源码
/**
* Interface for use with the ValueAnimator#setEvaluator(TypeEvaluator) function. Evaluators
* allow developers to create animations on arbitrary任意的 property types, by allowing them to supply
* custom evaluators for types that are not automatically understood and used by the animation system.
*/
public interface TypeEvaluator<T> {
/**
* This function returns the result of linearly interpolating the start and end values, with fraction representing
* the proportion比例 between the start and end values. The calculation is a simple parametric参数
* calculation: result = x0 + t * (x1 - x0), where "x0" is startValue, "x1" is endValue, and "t" is fraction.
* @param fraction The fraction from the starting to the ending values
* @return A linear interpolation between the start and end values, given the fraction parameter.
*/
public T evaluate(float fraction, T startValue, T endValue);
}
IntEvaluator 源码
/** This evaluator can be used to perform type interpolation between int values. */
public class IntEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
return (int)(startValue + fraction * (endValue - startValue));
}
}
FloatEvaluator 源码
public Float evaluate(float fraction, Number startValue, Number endValue) {
return startValue.floatValue() + fraction * (endValue.floatValue() - startValue.floatValue());
}
ArgbEvaluator 源码
/** integer values that represent ARGB colors. */
public class ArgbEvaluator implements TypeEvaluator {
/**
* This function returns the calculated in-between value for a color given integers that represent
* the start and end values in the four bytes of the 32-bit int. Each channel is separately单独的
* linearly interpolated and the resulting calculated values are recombined into the return value.
* @param fraction The fraction from the starting to the ending values
* @param startValue A 32-bit int value representing colors in the separate bytes of the parameter
* @param endValue A 32-bit int value representing colors in the separate bytes of the parameter
* @return A value that is calculated to be the linearly interpolated result, derived by separating
* the start and end values into separate color channels and interpolating each one separately,
* recombining the resulting values in the same way.
*/
public Object evaluate(float fraction, Object startValue, Object endValue) {
int startInt = (Integer) startValue;
int startA = (startInt >> 24) & 0xff;
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff;
int endInt = (Integer) endValue;
int endA = (endInt >> 24) & 0xff;
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff;
return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
(int)((startR + (int)(fraction * (endR - startR))) << 16) |
(int)((startG + (int)(fraction * (endG - startG))) << 8) |
(int)((startB + (int)(fraction * (endB - startB))));
}
}
自定义TypeEvaluator实现抛物线效果
自定义TypeEvaluator时传入的泛型可以根据自己的需求,自己设计个Bean。
为了以不同的函数分别设置x和y的位置,我们自定义的TypeEvaluator传入的泛型为PointF对象,每次根据当前时间返回一个PointF对象,PointF中的x、y代表View当前的位置,然后在监听动画绘制过程时更新UI。
自定义TypeEvaluator
public class PointFEvaluator implements TypeEvaluator<PointF> {
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
//只要能保证:当fraction=0时返回值为startValue,并且当fraction=1时返回值为endValue,就是一个比较合理的函数
PointF pointF = new PointF();
pointF.x = startValue.x + fraction * (endValue.x - startValue.x);// x方向匀速移动
pointF.y = startValue.y + fraction * fraction * (endValue.y - startValue.y);// y方向抛物线加速移动
return pointF;
}
}
在Activity中的使用
// 自定义TypeEvaluator实现抛物线动画效果
public class TypeEvaluatorActivity extends Activity {
private ImageView iv_src;
private boolean b = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);//取消标题栏
Bitmap bitmap = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setDither(true);
canvas.drawCircle(10, 10, 10, paint);
iv_src = new ImageView(this);
iv_src.setImageBitmap(bitmap);
setContentView(iv_src, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
b = !b;
Point point = new Point();
((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(point);
ValueAnimator animator = new ValueAnimator().setDuration(1000);
//通过new创建的ValueAnimator要明确的setObjectValues和setEvaluator,并且一定要先setObjectValues,再setEvaluator
if (b) animator.setObjectValues(new PointF(0, 0), new PointF(point.x - iv_src.getWidth(), point.y - iv_src.getHeight()));
else animator.setObjectValues(new PointF(0, point.y - iv_src.getHeight()), new PointF(point.x - iv_src.getWidth(), 0));
animator.setEvaluator(new PointFEvaluator());//PointFEvaluator为自定义的估值器,其实就是用来封装你需要的数据用的
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF point = (PointF) animation.getAnimatedValue();
iv_src.setX(point.x);
iv_src.setY(point.y);
}
});
animator.start();
}
return super.onTouchEvent(event);
}
}
最新文章
- 那些年我们一起过的JS闭包,作用域,this,让我们一起划上完美的句号。
- C#字符串处理(String与StringBuilder)
- C#之参数线程
- 搭建SpringMVC+MyBatis开发框架二
- VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)
- PyQt4学习笔记2:事件和信号
- CentOS 如何将.deb 文件 转换.rpm
- lc面试准备:Regular Expression Matching
- close函数
- Failed to load resource: the server responded with a status of 413 (Request Entity Too Large)
- asp.net错误.在应用程序级别之外使用注册为 allowDefinition=&#39;MachineToApplication&#39; 的节是错
- 总结一些php的面试题
- 难受的ESlint语法检测
- Python3练习题 018:打印星号菱形
- 玩转EhCache之最简单的缓存框架
- 网络编程-day1
- Python+Selenium学习--控制浏览器控制条
- [administrative][lvm] lvm 分区修改
- 【leetcode】27-RemoveElement
- python------面向对象介绍之经典类与新式类的继承顺序