国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - 一篇文章帶給你動畫估值器詳解

一篇文章帶給你動畫估值器詳解

2021-12-28 23:09Android開發編程 Android

TypeEvaluator的中文翻譯為類型估值算法,也叫估值器,它的作用是根據當前屬性改變的百分比來計算改變后的屬性值.

一篇文章帶給你動畫估值器詳解

前言

TypeEvaluator的中文翻譯為類型估值算法,也叫估值器,它的作用是根據當前屬性改變的百分比來計算改變后的屬性值,系統預置的有IntEvaluator(針對整型屬性)、FloatEvaluator(針對浮點型數據)和ArgbEvaluator(針對Color屬性);

屬性動畫中的插值器(Interpolator)和估值器(TypeEvalutor)很重要,它們是實現非勻速動畫的重要手段;

之前我們已經較少過插值器了,今天我們來介紹下估值器;

一、估值器詳解

1、應用場景

  • 插值器(Interpolator)決定值的變化規律(勻速、加速blabla),即決定的是變化趨勢,而接下來的具體變化數值則交給估值器;
  • 屬性動畫特有的屬性;
  • 非線性運動:動畫改變的速率不是一成不變的,如加速 & 減速運動都屬于非線性運動;

2、具體使用

2.1. 設置方式

  1. ObjectAnimator anim = ObjectAnimator.ofObject(myView2, "height", new Evaluator(),1,3);
  2. // 在第4個參數中傳入對應估值器類的對象
  3. // 系統內置的估值器有3個:
  4. // IntEvaluator:以整型的形式從初始值 - 結束值 進行過渡
  5. // FloatEvaluator:以浮點型的形式從初始值 - 結束值 進行過渡
  6. // ArgbEvaluator:以Argb類型的形式從初始值 - 結束值 進行過渡
  7. 點型插值器:FloatEvaluator
  8. public class FloatEvaluator implements TypeEvaluator {
  9. // FloatEvaluator實現了TypeEvaluator接口
  10. // 重寫evaluate()
  11. public Object evaluate(float fraction, Object startValue, Object endValue) {
  12. // 參數說明
  13. // fraction:表示動畫完成度(根據它來計算當前動畫的值)
  14. // startValue、endValue:動畫的初始值和結束值
  15. float startFloat = ((Number) startValue).floatValue();
  16. return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
  17. // 初始值 過渡 到結束值 的算法是:
  18. // 1. 用結束值減去初始值,算出它們之間的差值
  19. // 2. 用上述差值乘以fraction系數
  20. // 3. 再加上初始值,就得到當前動畫的值
  21. }
  22. }
  • 屬性動畫中的ValueAnimator.ofInt() & ValueAnimator.ofFloat()都具備系統內置的估值器,即FloatEvaluator & IntEvaluator;
  • 即系統已經默認實現了如何從初始值 過渡到結束值的邏輯;

2.2自定義估值器

  • 本質:根據插值器計算出當前屬性值改變的百分比 & 初始值 & 結束值,來計算當前屬性具體的數值;
  • 具體使用:自定義估值器需要實現 TypeEvaluator接口 & 復寫evaluate()
  1. public interface TypeEvaluator {
  2. public Object evaluate(float fraction, Object startValue, Object endValue) {
  3. // 參數說明
  4. // fraction:插值器getInterpolation()的返回值
  5. // startValue:動畫的初始值
  6. // endValue:動畫的結束值
  7. ....// 估值器的計算邏輯
  8. return xxx;
  9. // 賦給動畫屬性的具體數值
  10. // 使用反射機制改變屬性變化
  11. // 特別注意
  12. // 那么插值器的input值 和 估值器fraction有什么關系呢
  13. // input的值決定了fraction的值:input值經過計算后傳入到插值器的getInterpolation(),然后通過實現getInterpolation()中的邏輯算法,根據input值來計算出一個返回值,而這個返回值就是fraction了
  14. }
  15. }
  16. // 實現TypeEvaluator接口
  17. public class ObjectEvaluator implements TypeEvaluator{
  18. // 復寫evaluate()
  19. // 在evaluate()里寫入對象動畫過渡的邏輯
  20. @Override
  21. public Object evaluate(float fraction, Object startValue, Object endValue) {
  22. // 參數說明
  23. // fraction:表示動畫完成度(根據它來計算當前動畫的值)
  24. // startValue、endValue:動畫的初始值和結束值
  25. ... // 寫入對象動畫過渡的邏輯
  26. return value;
  27. // 返回對象動畫過渡的邏輯計算后的值
  28. }

3、自定義估值器

  • ValueAnimator.ofObject(),從工作原理可以看出并沒有系統默認實現估值器,因為對對象的動畫操作復雜 & 多樣,系統無法知道如何從初始對象過度到結束對象;
  • 因此,對于ValueAnimator.ofObject(),我們需自定義估值器(TypeEvaluator)來告知系統如何進行從初始對象過渡到結束對象的邏輯;

3.1定義對象

因為ValueAnimator.ofObject()是面向對象操作的,所以需要自定義對象類;

  1. public class Point {
  2. // 設置兩個變量用于記錄坐標的位置
  3. private float x;
  4. private float y;
  5. // 構造方法用于設置坐標
  6. public Point(float x, float y) {
  7. this.x = x;
  8. this.y = y;
  9. }
  10. // get方法用于獲取坐標
  11. public float getX() {
  12. return x;
  13. }
  14. public float getY() {
  15. return y;
  16. }
  17. }

3.2實現TypeEvaluator接口

實現TypeEvaluator接口的目的是自定義如何 從初始點坐標 過渡 到結束點坐標;

本例實現的是一個從左上角到右下角的坐標過渡邏輯。

// 實現TypeEvaluator接口

  1. public class PointEvaluator implements TypeEvaluator {
  2. // 復寫evaluate()
  3. // 在evaluate()里寫入對象動畫過渡的邏輯
  4. @Override
  5. public Object evaluate(float fraction, Object startValue, Object endValue) {
  6. // 將動畫初始值startValue 和 動畫結束值endValue 強制類型轉換成Point對象
  7. Point startPoint = (Point) startValue;
  8. Point endPoint = (Point) endValue;
  9. // 根據fraction來計算當前動畫的x和y的值
  10. float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());
  11. float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());
  12. // 將計算后的坐標封裝到一個新的Point對象中并返回
  13. Point point = new Point(x, y);
  14. return point;
  15. }
  16. }

3.3屬性動畫作用到自定義View當中

一篇文章帶給你動畫估值器詳解

  1. public class MyView extends View {
  2. // 設置需要用到的變量
  3. public static final float RADIUS = 70f;// 圓的半徑 = 70
  4. private Point currentPoint;// 當前點坐標
  5. private Paint mPaint;// 繪圖畫筆
  6. // 構造方法(初始化畫筆)
  7. public MyView(Context context, AttributeSet attrs) {
  8. super(context, attrs);
  9. // 初始化畫筆
  10. mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  11. mPaint.setColor(Color.BLUE);
  12. }
  13. // 復寫onDraw()從而實現繪制邏輯
  14. // 繪制邏輯:先在初始點畫圓,通過監聽當前坐標值(currentPoint)的變化,每次變化都調用onDraw()重新繪制圓,從而實現圓的平移動畫效果
  15. @Override
  16. protected void onDraw(Canvas canvas) {
  17. // 如果當前點坐標為空(即第一次)
  18. if (currentPoint == null) {
  19. currentPoint = new Point(RADIUS, RADIUS);
  20. // 創建一個點對象(坐標是(70,70))
  21. // 在該點畫一個圓:圓心 = (70,70),半徑 = 70
  22. float x = currentPoint.getX();
  23. float y = currentPoint.getY();
  24. canvas.drawCircle(x, y, RADIUS, mPaint);
  25. // (重點關注)將屬性動畫作用到View
  26. // 步驟1:創建初始動畫時的對象點 & 結束動畫時的對象點
  27. Point startPoint = new Point(RADIUS, RADIUS);// 初始點為圓心(70,70)
  28. Point endPoint = new Point(700, 1000);// 結束點為(700,1000)
  29. // 步驟2:創建動畫對象 & 設置初始值 和 結束值
  30. ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
  31. // 參數說明
  32. // 參數1:TypeEvaluator 類型參數 - 使用自定義的PointEvaluator(實現了TypeEvaluator接口)
  33. // 參數2:初始動畫的對象點
  34. // 參數3:結束動畫的對象點
  35. // 步驟3:設置動畫參數
  36. anim.setDuration(5000);
  37. // 設置動畫時長
  38. // 步驟3:通過 值 的更新監聽器,將改變的對象手動賦值給當前對象
  39. // 此處是將 改變后的坐標值對象 賦給 當前的坐標值對象
  40. // 設置 值的更新監聽器
  41. // 即每當坐標值(Point對象)更新一次,該方法就會被調用一次
  42. anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  43. @Override
  44. public void onAnimationUpdate(ValueAnimator animation) {
  45. currentPoint = (Point) animation.getAnimatedValue();
  46. // 將每次變化后的坐標值(估值器PointEvaluator中evaluate()返回的Piont對象值)到當前坐標值對象(currentPoint)
  47. // 從而更新當前坐標值(currentPoint)
  48. // 步驟4:每次賦值后就重新繪制,從而實現動畫效果
  49. invalidate();
  50. // 調用invalidate()后,就會刷新View,即才能看到重新繪制的界面,即onDraw()會被重新調用一次
  51. // 所以坐標值每改變一次,就會調用onDraw()一次
  52. }
  53. });
  54. anim.start();
  55. // 啟動動畫
  56. } else {
  57. // 如果坐標值不為0,則畫圓
  58. // 所以坐標值每改變一次,就會調用onDraw()一次,就會畫一次圓,從而實現動畫效果
  59. // 在該點畫一個圓:圓心 = (30,30),半徑 = 30
  60. float x = currentPoint.getX();
  61. float y = currentPoint.getY();
  62. canvas.drawCircle(x, y, RADIUS, mPaint);
  63. }
  64. }
  65. }

原文鏈接:https://mp.weixin.qq.com/s/EF4SihTH1ZJ9uxSU6iROkA

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品99久久久久久动医院 | yellow在线视频免费观看 | 一区在线播放 | 午夜影院在线观看 | 久久伊99综合婷婷久久伊 | 久久九| 真人一级毛片 | 99草在线视频 | 亚洲精品午夜 | 91视频免费看| 亚洲精品日本 | 在线观看亚洲成人 | 国产欧美综合一区二区三区 | 亚洲国产精品久久久久久 | 亚洲精品日韩精品 | 国产精品久久九九 | 亚洲精品天堂 | 精品久久久久一区二区国产 | 国产精品久久久久久久久久久久久 | 亚洲国内精品 | 男人天堂亚洲 | 欧美日韩在线精品 | 99看| 狠狠淫| 亚洲人视频在线观看 | 久久艹天天艹 | 亚洲男人的天堂网站 | 亚洲三级不卡 | 99热这里有精品 | 亚洲精品国产区欧美区在线 | 成人片网址 | 国产综合久久久 | av超碰| 久久国产一区二区 | 亚洲第一视频 | 欧美精产国品一二三区 | 91av爱爱| 免费观看一区二区三区 | 欧美午夜影院 | 国产精品久久久久久久久 | 国产一级在线 |