首先先說下自己理解的MVC模式:
M即是model 數據模型對象 V 即是View是視圖顯示數據的地方,通常Model的數據構造View, C即是Controller 負責Model和View交互、
下面看看百度的說法
MMVC 編程模式編輯
-
Model(模型)表示應用程序核心(比如數據庫記錄列表)。
-
View(視圖)顯示數據(數據庫記錄)。
-
Controller(控制器)處理輸入(寫入數據庫記錄)。
通常模型對象負責在數據庫中存取數據。
通常視圖是依據模型數據創建的。
通常控制器負責從視圖讀取數據,控制用戶輸入,並向模型發送數據。
1.下面講一下Property Animation 屬性動畫的擴展動畫ObjectAnimator
ValueAnimator的子類,
要指定一個對象及該對象的一個屬性,當屬性值計算完成時自動設置爲該對象的相應屬性,即完成了Property Animation的全部兩步操作。實際應用中一般都會用ObjectAnimator來改變某一對象的某一屬性,但用ObjectAnimator有一定的限制,要想使用ObjectAnimator,應該滿足以下條件:
- 對象應該有一個setter函數:set<PropertyName>(駝峯命名法)
- 如上面的例子中,像ofFloat之類的工場方法,第一個參數爲對象名,第二個爲屬性名,後面的參數爲可變參數,如果values…參數只設置了一個值的話,那麼會假定爲目的值,屬性值的變化範圍爲當前值到目的值,爲了獲得當前值,該對象要有相應屬性的getter方法:get<PropertyName>
- 如果有getter方法,其應返回值類型應與相應的setter方法的參數類型一致。
如果上述條件不滿足,則不能用ObjectAnimator,應用ValueAnimator代替。
2.下面就objectAnimator的ofObject方法來舉一個例子
由於是動態圖我就不耗時做動態圖了,具體的內容就是點擊按鈕原先的畫好的樹狀圖緩緩上升。接下來就直接講解例子了
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);
}
}
}
具體的我都是有註釋: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就不做解釋了
效果最後就是柱子慢慢上升。