Fling Animation也是一种基于物流的动画之一。它提供了一种物体运动减速的效果,受速度和摩擦力所影响,比如:
[外链图片转存失败(img-VKgQGdZ4-1563080333644)(https://developer.android.com/images/guide/topics/graphics/fling-animation.gif)]
为了使用基于物理的动画,我们需要添加一个官方提供的扩展库:
当你的v7版本是28以上,即为AndroidX时,导入:
dependencies {
implementation 'androidx.dynamicanimation:dynamicanimation:1.1.0-alpha01'
}
否则,导入:
dependencies {
implementation 'com.android.support:support-dynamic-animation:25.3.0'
}
如果版本不对应,导入错误会导致无法编译程序。
FlingAnimation(iv_view, DynamicAnimation.TRANSLATION_X)
运动的速度相当于给物体的一个初始力,决定着物体运动的方向和效果。
FlingAnimation(iv_view, DynamicAnimation.TRANSLATION_X).apply {
setStartVelocity(100f)
}
物体属性值的动画值范围限制了物体的移动的范围,以防止受力过大导致移除视图外的情况出现。
var minValue=0f
var maxValue=100.0f
FlingAnimation(iv_view, DynamicAnimation.TRANSLATION_X).apply {
//设置动画值范围
setMinValue(minValue)
setMaxValue(maxValue)
}
按照物理运动规则,只有受到摩擦力的作用,运动的物体才会停止。在相同的力和速度的情况下,摩擦力越大,物体越快停止。
FlingAnimation(iv_view, DynamicAnimation.TRANSLATION_X).apply {
// 设置摩擦力
friction=1.1f
}
FlingAnimation(iv_view, DynamicAnimation.TRANSLATION_X).apply {
// 设置运动速度
setStartVelocity(velocityX)
// 设置动画值范围
setMinValue(minValue)
setMaxValue(maxValue)
// 设置摩擦力
friction=1.1f
// 启动动画
start()
}
**FlingAnimation.setMinimumVisibleChange()**为动画未以pixels定义的自定义属性设置时,提供对用户可见动画值的最小更改。它确定了结束动画的合理阀值。
但是DynamicAnimation.ViewProperty提供的属性值不需要设置这个方法,因为**FlingAnimation.setMinimumVisibleChange()**本身就是从其属性值派生出来的。
Android 系统本身提供了四种最小可见更改常量:
class FlingAnimationActivity : AppCompatActivity() {
lateinit var gestureDetector: GestureDetector
var maxTranslationX: Int? = null
var maxTranslationY: Int? = null
private val gestureListener = object : GestureDetector.SimpleOnGestureListener() {
override fun onDown(e: MotionEvent?): Boolean {
return true
}
override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean {
// 计算出水平或垂直方向上最大的绝对值速度,取用最大的速度方向进行移动
if (Math.abs(velocityX) > Math.abs(velocityY)) {
FlingAnimation(iv_view, DynamicAnimation.TRANSLATION_X).apply {
setStartVelocity(velocityX)
setMinValue(0f)
setMaxValue(maxTranslationX!!.toFloat())
friction=1.1f
start()
}
}else{
FlingAnimation(iv_view,DynamicAnimation.TRANSLATION_Y).apply {
setStartVelocity(velocityY)
setMinValue(0f)
setMaxValue(maxTranslationY!!.toFloat())
friction=1.1f
start()
}
}
return true
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_fling_animation)
//计算View在水平方向和垂直方向上
root.viewTreeObserver.addOnGlobalLayoutListener {
maxTranslationX=root.width-iv_view.width
maxTranslationY=root.height-iv_view.height
}
//利用GestureDetector检测Fling事件
gestureDetector= GestureDetector(this,gestureListener)
//将View的Touch事件分发到GestureDetector处理
iv_view.setOnTouchListener { v, event ->
gestureDetector.onTouchEvent(event)
}
}
}
案例代码中,为达到简单的滑动View的效果,我们把View放在左上角,并且完成如下计算: