天天看點

Property Animation之ObjectAnimator動畫樹狀圖上升增長效果 1.下面講一下Property Animation 屬性動畫的擴充動畫ObjectAnimator

首先先說下自己了解的MVC模式:

M即是model 資料模型對象  V 即是View是視圖顯示資料的地方,通常Model的資料構造View, C即是Controller 負責Model和View互動、

下面看看百度的說法

MMVC 程式設計模式編輯

MVC 是一種使用 MVC(Model View Controller 模型-視圖-控制器)設計建立 Web 應用程式的模式: [1]  

  • Model(模型)表示應用程式核心(比如資料庫記錄清單)。
  • View(視圖)顯示資料(資料庫記錄)。
  • Controller(控制器)處理輸入(寫入資料庫記錄)。

MVC 模式同時提供了對 HTML、CSS 和 JavaScript 的完全控制。 Model(模型)是應用程式中用于處理應用程式資料邏輯的部分。

  通常模型對象負責在資料庫中存取資料。 View(視圖)是應用程式中處理資料顯示的部分。

  通常視圖是依據模型資料建立的。 Controller(控制器)是應用程式中處理使用者互動的部分。

  通常控制器負責從視圖讀取資料,控制使用者輸入,并向模型發送資料。 MVC 分層有助于管理複雜的應用程式,因為您可以在一個時間内專門關注一個方面。例如,您可以在不依賴業務邏輯的情況下專注于視圖設計。同時也讓應用程式的測試更加容易。 MVC 分層同時也簡化了分組開發。不同的開發人員可同時開發視圖、控制器邏輯和業務邏輯。

1.下面講一下Property Animation 屬性動畫的擴充動畫ObjectAnimator

         objectAnimatior是  

ValueAnimator的子類,

要指定一個對象及該對象的一個屬性,當屬性值計算完成時自動設定為該對象的相應屬性,即完成了Property Animation的全部兩步操作。實際應用中一般都會用ObjectAnimator來改變某一對象的某一屬性,但用ObjectAnimator有一定的限制,要想使用ObjectAnimator,應該滿足以下條件:

  • 對象應該有一個setter函數:set<PropertyName>(駝峰命名法)
  • 如上面的例子中,像ofFloat之類的工場方法,第一個參數為對象名,第二個為屬性名,後面的參數為可變參數,如果values…參數隻設定了一個值的話,那麼會假定為目的值,屬性值的變化範圍為目前值到目的值,為了獲得目前值,該對象要有相應屬性的getter方法:get<PropertyName>
  • 如果有getter方法,其應傳回值類型應與相應的setter方法的參數類型一緻。

  如果上述條件不滿足,則不能用ObjectAnimator,應用ValueAnimator代替。

2.下面就objectAnimator的ofObject方法來舉一個例子

    由于是動态圖我就不耗時做動态圖了,具體的内容就是點選按鈕原先的畫好的樹狀圖緩緩上升。接下來就直接講解例子了

Property Animation之ObjectAnimator動畫樹狀圖上升增長效果 1.下面講一下Property Animation 屬性動畫的擴充動畫ObjectAnimator

首先我們先來了解ChartView這個類,先從View講解更容易了解:

public class ChartView extends View {
	ShapeDrawable mDrawableagain;
	// 這個類裡面存放了我們的List<Bar>資料也就是我們的樹狀圖資料
	BarChartData barChartData = null;
	Paint paint;

	public ChartView(Context context) {
		super(context);
		paint = new Paint();
		barChartData = new BarChartData();
	}

	// 調用onDraw
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		//循環barChartData對象取出樹狀圖的參數并畫出
		for (int i = 0; i < barChartData.getBarlist().size(); i++) {
			Bar bardataBar = barChartData.getBarlist().get(i);
			paint.setColor(Color.BLUE);
			paint.setStrokeWidth(2);
			canvas.drawRect(bardataBar.getX(), bardataBar.getY(),
					bardataBar.getWidth(), bardataBar.getHeight(), paint);
		}

	}

}
           

具體的我都是有注釋: 主程式實作C控制MV

public class MainActivity extends Activity {
	private Button startButton;
	ChartView view;
	ValueAnimator bounceAnim = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		LinearLayout container = (LinearLayout) findViewById(R.id.container);
		startButton = (Button) findViewById(R.id.startButton);
		view = new ChartView(this);
		// 繪制樹狀圖的初始資料
		List<Bar> barlist = new ArrayList<Bar>();
		barlist.add(addTreeView(200, 200, 380, 580));
		barlist.add(addTreeView(480, 300, 660, 580));
		barlist.add(addTreeView(760, 100, 940, 580));
		barlist.add(addTreeView(1040, 300, 1220, 580));
		view.barChartData.setBarlist(barlist);
		view.setBackgroundColor(Color.RED);
		container.addView(view);
		startButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// 點選産生動畫
				createAnimator();
			}
		});

	}

	public void createAnimator() {
		if (bounceAnim == null) {
			// 傳入初狀态與末狀态實作動畫效果
			BarChartData startXY = new BarChartData();
			List<Bar> barlist = new ArrayList<Bar>();
			barlist.add(addTreeView(200, 200, 380, 580));
			barlist.add(addTreeView(480, 300, 660, 580));
			barlist.add(addTreeView(760, 100, 940, 580));
			barlist.add(addTreeView(1040, 300, 1220, 580));
			startXY.setBarlist(barlist);
			BarChartData endXY = new BarChartData();
			List<Bar> barlist2 = new ArrayList<Bar>();
			barlist2.add(addTreeView(200, 100, 380, 580));
			barlist2.add(addTreeView(480, 100, 660, 580));
			barlist2.add(addTreeView(760, 50, 940, 580));
			barlist2.add(addTreeView(1040, 200, 1220, 580));
			endXY.setBarlist(barlist2);
			// 這裡我用的是 ObjectAnimator的 ofObject (Object target, String
			// propertyName, TypeEvaluator evaluator, Object... values)方法
			// ObjectAnimator的構造使用了ofObject形式的工廠方法,傳入了自定義的evaluator對象
			// 第一個參數表示的是屬性變化的對象,而且這個對象要有一個公共的方法setName()方法,裡面的Name有一個propertyName的參數
			// 的值,第二個參數propertyName就是第一個參數被動畫的屬性
			// 第三個參數表示的是 evaluator這個函數傳回的結果線性插值的開始和結束值,用分數表示開始和結束之間的比例值
			// 這個對象具體看XYWHEvaluator這個類,最後兩個參數就是第一個對象的初狀态與末狀态。動畫其實主要是看evaluator這個參數
			bounceAnim = ObjectAnimator.ofObject(view.barChartData, "barlist",
					new XYWHEvaluator(), startXY, endXY);
			// 設定動畫的時間
			bounceAnim.setDuration(3000);

			bounceAnim.addUpdateListener(new AnimatorUpdateListener() {
				@Override
				public void onAnimationUpdate(ValueAnimator animation) {
					// 将要變化的參數傳入View中,在對其進行重繪
					view.barChartData.setBarlist(((BarChartData) animation
							.getAnimatedValue()).getBarlist());
					// invalidate 函數的主要作用是請求View樹進行重繪
					view.invalidate();
				}
			});
			// 開始這個動畫
			bounceAnim.start();
		}

	}

	// 存儲資料用的
	private Bar addTreeView(int x, int y, int width, int height) {
		Bar mbardata = new Bar(x, y, width, height);
		mbardata.setX(x);
		mbardata.setY(y);
		mbardata.setWidth(width);
		mbardata.setHeight(height);
		return mbardata;
	}

}
           

動畫的重要類XYWHEvaluator

// 實作自己的TypeEvaluator
// 傳入fraction和兩個XYHolder類型的對象
// 傳回一個XYHolder對象,其坐标值為兩個輸入參數的相應值線性插值的結果
//public abstract T evaluate (float fraction, T startValue, T endValue)
public class XYWHEvaluator implements TypeEvaluator<BarChartData> {
	// 這個類就是動畫的核心,這裡我把BarChartData當作了一個整體裡面封裝了樹狀圖的資料,
	// 需要做的是将BarChartData當作一個對象,我們要抽象出樹狀圖的上升過程
	// 具體實作就是evaluate的動畫公式 result = x0 + t * (v1 - v0),
	// 我們需要的是對樹狀圖取到上升的效果也就是對其的Y軸參數進行修改
	@Override
	public BarChartData evaluate(float fraction, BarChartData startValue,
			BarChartData endValue) {
		// TODO Auto-generated method stub
		BarChartData barChartData = new BarChartData();
		// 構造一個List<bar>的數組,裡面存儲的就是bar的變化值,上升隻需要算出Y軸的變化
		List<Bar> listBar = new ArrayList<Bar>();
		for (int i = 0; i < startValue.getBarlist().size(); i++) {
			// 得到Y軸的數值
			Bar bardata = startValue.getBarlist().get(i);
			Bar bardata2 = endValue.getBarlist().get(i);
			// 通過公式算Y軸變化,公式的意思就是物體的初狀态即x0加上fraction×(末狀态與初狀态的內插補點)
			// 這裡的fraction可以了解為百分比,這個時段我增長了多少,總增長×百分比加上初狀态就是此時的狀态
			// 這裡的了解僅僅是我自己的了解,有錯的希望指正
			float y = bardata.getY() + fraction
					* (bardata2.getY() - bardata.getY());
			float x = bardata.getX();
			float width = bardata.getWidth();
			float height = bardata.getHeight();
			Bar bar = new Bar(x, y, width, height);
			listBar.add(bar);
		}
		// 将變化後的bar數值放入barChartData中去就實作這個對象某時刻的狀态
		barChartData.setBarlist(listBar);
		return barChartData;
	}
}
           

對象類

</pre><pre name="code" class="java">package com.example.barview;

import java.util.ArrayList;
import java.util.List;

//這個類就是包含屬性的對象
public class BarChartData {
	// 對List<Bar>進行set與get方法 也就是實作objectanimatior所需要的條件
	private List<Bar> barlist = new ArrayList<Bar>();

	public List<Bar> getBarlist() {
		return barlist;
	}

	public void setBarlist(List<Bar> barlist) {
		this.barlist = barlist;
	}

}
           
package com.example.barview;

import android.graphics.drawable.ShapeDrawable;

public class Bar {
	float x;
	float y;
	float width;
	float height;

	Bar(float x, float y, float width, float height) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
	}

	public float getX() {
		return x;
	}

	public void setX(float f) {
		this.x = f;
	}

	public float getY() {
		return y;
	}

	public void setY(float f) {
		this.y = f;
	}

	public float getWidth() {
		return width;
	}

	public void setWidth(float width) {
		this.width = width;
	}

	public float getHeight() {
		return height;
	}

	public void setHeight(float height) {
		this.height = height;
	}

}
           

布局的話我就放了一個Button就不做解釋了 下面看一下大緻的效果圖其實有動畫的

Property Animation之ObjectAnimator動畫樹狀圖上升增長效果 1.下面講一下Property Animation 屬性動畫的擴充動畫ObjectAnimator

效果最後就是柱子慢慢上升。 下面是檔案的下載下傳位址:http://download.csdn.net/detail/kluing/7971061