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方法来举一个例子

    由于是动态图我就不耗时做动态图了,具体的内容就是点击按钮原先的画好的树状图缓缓上升。接下来就直接讲解例子了



首先我们先来了解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就不做解释了
下面看一下大致的效果图其实有动画的


效果最后就是柱子慢慢上升。
下面是文件的下载地址:http://download.csdn.net/detail/kluing/7971061




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值