Android動畫-Fling Animation

Android動畫-Fling Animation

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'
  }
  

如果版本不對應,導入錯誤會導致無法編譯程序。

創建Fling Animation的流程

  • 創建Fling Animation對象
  • 設置一個運動速度
  • 設置一個動畫值範圍
  • 設置摩擦力
  • 設置最小可見更改(可選)

創建Fling Animation對象

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 系統本身提供了四種最小可見更改常量:

  • MIN_VISIBLE_CHANGE_PIXELS:默認值爲1f.作用域TRANSLATION_XTRANSLATION_XTRANSLATION_ZSCROLL_XSCROLL_Y
  • MIN_VISIBLE_CHANGE_ROTATION_DEGREES:默認值爲1/10pixel.作用於ROTATIONROTATION_XROTATION_Y
  • MIN_VISIBLE_CHANGE_ALPHA:默認值1f / 256f。作用於透明度的屬性。
  • MIN_VISIBLE_CHANGE_SCALE:默認值1f / 500f。作用於縮放的屬性。

編寫一個Fling Animation的小Demo

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放在左上角,並且完成如下計算:

  • 通過 父佈局和寬高-View的寬高計算出=View的可見範圍
  • 使用工具類GestureDetector通過監聽從View的Touch事件中分發出來的Fling事件。
  • 只移動絕對值最大的方向
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章