Android ObjectAnimator 更改视图位置
如果要改变某个View的位置,直接修改坐标会有一种刷的一下突然改变位置的感觉。
为了让它看起来更自然一些,我们可以加入动画,位置移动看起来更顺滑。
我们可以用ObjectAnimator
来实现动画效果。配合上时间插值器,能控制动画的加减速。
接下来用一些例子来说明ObjectAnimator
的用法。本文使用Kotlin来演示。
动画移动示例
mTv
是被我们操作的View。同时它显示了当前它的x,y
和translationX/Y
private val mUpdateListener = ValueAnimator.AnimatorUpdateListener {
mTv.text = "RustFisher\n(${mTv.x.toInt()},${mTv.y.toInt()}); (${mTv.translationX.toInt()},${mTv.translationY.toInt()})"
}
这个mUpdateListener
不用也行。这里只是为了显示坐标。
TRANSLATION_X
这个小例子是为了演示TRANSLATION_X
修改的动画。水平方向的动画,时常1秒。
val ani = ObjectAnimator.ofFloat(mTv, View.TRANSLATION_X, 0f, 200f, 640f).apply {
duration = 1000
}
ani.addUpdateListener(mUpdateListener)
ani.start()
使用静态方法ObjectAnimator.ofFloat
获得ObjectAnimator
对象。
ofFloat(T target, Property<T, Float> property, float... values)
- target 是要移动的对象,我们传入一个View
- property 是要更改的属性
- float… values 是目的数值
注意这里都是用float。values
里我们传入了3个数字。开始到结束时从0变化到640。
动画将会分成2个部分,前500毫秒是0到200;后500毫秒是200到640。
在apply
里,动画时间duration
设置为1000毫秒。
动画效果
可以看到,最后停止的位置并不是我们指定的640,而是差那么1像素。
实际上,如果不用监听器,可以写成这样
ObjectAnimator.ofFloat(mTv, View.TRANSLATION_X, 0f, 200f, 640f).apply {
duration = 1000
start()
}
TRANSLATION_Y
同理,我们也可以改变View.TRANSLATION_Y
val ani = ObjectAnimator.ofFloat(mTv, View.TRANSLATION_Y, 100f).apply {
duration = 1000
}
ani.addUpdateListener(mUpdateListener)
ani.start()
values里只传入了100f。表示从当前值变化到100f。这个是目标值。
X,Y
我们也可以直接改变View的X和Y
val ani = ObjectAnimator.ofFloat(mTv, View.X, 500f).apply {
duration = 800
}
ani.addUpdateListener(mUpdateListener)
ani.start()
// 或者
val ani = ObjectAnimator.ofFloat(mTv, View.Y, 700f).apply {
duration = 700
}
ani.addUpdateListener(mUpdateListener)
ani.start()
上下左右
可以以View当前位置为出发点,计算出目标点。实现一个控制上下左右移动的效果。
例如控制向上,让Y减少100。
val ani = ObjectAnimator.ofFloat(mTv, View.Y, mTv.y - 100).apply {
duration = 200
}
ani.addUpdateListener(mUpdateListener)
ani.start()
沿指定路径移动
除了水平/垂直移动,我们还可以指定一个路径给动画。
要用到Path
类。
圆弧
指定一个圆弧路径。Path().apply{ }
里指定圆弧的参数。
val path = Path().apply {
arcTo(0f, 0f, 960f, 1200f, 270f, -180f, true)
}
val ani = ObjectAnimator.ofFloat(mTv, View.X, View.Y, path).apply {
duration = 2000
}
ani.addUpdateListener(mUpdateListener)
ani.start()
折线
同样是利用Path
,我们自己绘制一个折线路线。
val path = Path().apply {
moveTo(0f, 0f)
lineTo(800f, 400f)
lineTo(0f, 600f)
lineTo(800f, 800f)
lineTo(0f, 1000f)
}
val ani = ObjectAnimator.ofFloat(mTv, View.X, View.Y, path).apply {
duration = 3000
}
ani.addUpdateListener(mUpdateListener)
ani.start()
这是个长达3秒的动画。从(0,0)
出发,最后抵达(0,1000)
。视觉上就是走了一个折线。
创建Path时,先moveTo(0f, 0f)
回到(0,0)
,然后用lineTo
把路径绘制出来。
参考
- 点赞
- 收藏
- 关注作者
评论(0)