android自定义动画
前一篇说了实现过程,这次来写一个自己简单实现的3d动画
先来属性声明配置,方便使用xml 文件来定制动画
<!-- 有些类型其实是没必要的,只是实例代码,为了更具有代表性 -->
<declare-styleable name="CubeAnimation">
<attr name="fromX" format="dimension|fraction|float"/>
<attr name="toX" format="dimension|fraction|float"/>
<attr name="fromDegree" format="float"/>
<attr name="toDegree" format="float"/>
<attr name="axisY" format="float|integer"/>
<attr name="positive" format="boolean"/>
</declare-styleable>
配置参数相关的一些解释
dimension 像素值类型,包括有"px", "dip", "sp", "pt", "in", "mm", 一般用TypedValue.complexToDimension解析
fraction 分数,一般用来表示占的百分比,"%", "%p"。 一般用TypedValue.complexToFraction解析 有时候和float类型功能通用
float 浮点数。当确定是这个类型的时候,用TypedValue.getFloat解析
integer 整数,TypedValue.data 就是这个值。
后两者,如果参数只有确定的一个类型,直接用TypedArray 的 getInteger 或者 getFloat方法就可以获取
动画配置
<!-- 命名空间神马的就不说了 -->
<?xml version="1.0" encoding="utf-8"?>
<cube
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cs="http://schemas.android.com/apk/res/com.example.testwifi"
android:duration="2000"
android:repeatCount="5"
cs:fromDegree="0"
cs:toDegree="1440"
cs:fromX="50"
cs:toX="90%p"
cs:axisY="0.5"
cs:positive="true"/>
包含在集合内的动画配置
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cs="http://schemas.android.com/apk/res/com.example.testwifi">
<cube
cs:fromDegree="0"
cs:toDegree="1440"
cs:fromX="50"
cs:toX="90%p"
cs:axisY="0.5"
cs:positive="true/>
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="700" />
</set>
动画类的代码
public class CubeAnimation extends Animation { private float mFromDegrees;
private float mToDegrees; private int mFromXType = ABSOLUTE;;
private float mFromX = 0;
private int mFromXdata = 0; private int mToXType = ABSOLUTE;
private float mToX = 0;
private int mToXData = 0; private Camera mCamera;
private Resources mResources;
private float mAxisY = 0;
private int mAxisYType = ABSOLUTE; public CubeAnimation(float fromX,float toX,float fromDegree,float toDegree,float axisY) {
this.mFromX = fromX;
this.mToX = toX;
this.mFromDegrees = fromDegree;
this.mToDegrees = toDegree;
this.mAxisY = axisY; mFromXType = TypedValue.TYPE_FLOAT;
mToXType = TypedValue.TYPE_FLOAT;
mAxisYType = ABSOLUTE; }
public CubeAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CubeAnimation);
mResources = context.getResources();
TypedValue value = a.peekValue(R.styleable.CubeAnimation_fromX);
if(value.type==TypedValue.TYPE_FLOAT){
this.mFromX = value.getFloat();
this.mFromXType = value.type;
}else{
this.mFromXType = value.type;
this.mFromXdata = value.data;
} value = a.peekValue(R.styleable.CubeAnimation_toX);
if(value.type==TypedValue.TYPE_FLOAT){//FLOAT 类型的,必须在这里解析了,因为下边的resolveData 方法拿不到TypedValue,没法解析
this.mToX = value.getFloat();
this.mToXType = value.type;
}else{
this.mToXType = value.type;
this.mToXData = value.data;
}
boolean t = a.getBoolean(R.styleable.CubeAnimation_positive, true);
if (!(t)) {
this.mToDegrees = 0.0F;
this.mFromDegrees = 90.0F;
}
this.mFromDegrees = a.getFloat(R.styleable.CubeAnimation_fromDegree, 0);
this.mToDegrees = a.getFloat(R.styleable.CubeAnimation_toDegree, 90); value = a.peekValue(R.styleable.CubeAnimation_axisY);
this.mAxisYType = value.type;
//参数不同类型用来做什么用,按自己需求来设定和解析,我这里配置文件属性要求是两种 <attr name="axisY" format="float|integer"/>
//如果是float类型,则做用来做组件的比例 如果是int型,认为是像素值
if(this.mAxisYType==TypedValue.TYPE_FLOAT){
this.mAxisY = value.getFloat();
this.mAxisYType = RELATIVE_TO_SELF;
}else{
this.mAxisY = value.data;
}
a.recycle();
} public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
if(this.mFromXType!=TypedValue.TYPE_FLOAT){//这里Float类型代表固定值,且已经解析过,不再解析 下同
this.mFromX = resolveData(this.mFromXType,this.mFromXdata, width,
parentWidth);
}
if(mToXType!=TypedValue.TYPE_FLOAT){
this.mToX = resolveData(this.mToXType,this.mToXData,width,parentWidth);
}
this.mCamera = new Camera(); if(mAxisYType==RELATIVE_TO_SELF) {//如果是相对自身的大小比例,则按比例计算获取对应值。否则,则为固定像素值
mAxisY = mAxisY*height;
}
System.out.println("mFromX="+mFromX+",mToX=="+mToX);
}
float resolveData( int type, int data, int size, int psize) {
float value = 0;
if (type == TypedValue.TYPE_FRACTION) {
value = TypedValue.complexToFraction(data, size, psize);
} else if (type == TypedValue.TYPE_DIMENSION) {
value = TypedValue.complexToDimension(data, mResources.getDisplayMetrics());
} else{//如果是由代码设置成的ABSOLUTE类型或者 配置文件本身就是int的固定值
value= data;
}
return value;
} // 自定义动画主要要实现的方法
protected void applyTransformation(float interpolatedTime, Transformation t) {
float fromDegrees = this.mFromDegrees;
float degrees = fromDegrees + (this.mToDegrees - fromDegrees)
* interpolatedTime; Camera camera = this.mCamera; Matrix matrix = t.getMatrix(); camera.save();
camera.rotateX(degrees); camera.getMatrix(matrix);
camera.restore(); matrix.postTranslate(mFromX+(mToX-mFromX)*interpolatedTime, this.mAxisY); } // 因为用AnimationUtils无法解析出这个动画的属性,所以所有CubeAnimation的配置文件或者包含这个动画的set配置文件,必须用这个方法加载
public static Animation loadAnimation(Context context, int id)
throws NotFoundException { XmlResourceParser parser = null;
try {
parser = context.getResources().getAnimation(id);
return createAnimationFromXml(context, parser, null,
Xml.asAttributeSet(parser));
} catch (XmlPullParserException ex) {
NotFoundException rnf = new NotFoundException(
"Can't load animation resource ID #0x"
+ Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} catch (IOException ex) {
NotFoundException rnf = new NotFoundException(
"Can't load animation resource ID #0x"
+ Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} finally {
if (parser != null)
parser.close();
}
} private static Animation createAnimationFromXml(Context c,
XmlPullParser parser, AnimationSet parent, AttributeSet attrs)
throws XmlPullParserException, IOException { Animation anim = null;
// Make sure we are on a start tag.
int type;
int depth = parser.getDepth();
while (((type = parser.next()) != XmlPullParser.END_TAG || parser
.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("set")) {
anim = new AnimationSet(c, attrs);
createAnimationFromXml(c, parser, (AnimationSet) anim, attrs);
} else if (name.equals("alpha")) {
anim = new AlphaAnimation(c, attrs);
} else if (name.equals("scale")) {
anim = new ScaleAnimation(c, attrs);
} else if (name.equals("rotate")) {
anim = new RotateAnimation(c, attrs);
} else if (name.equals("translate")) {
anim = new TranslateAnimation(c, attrs);
} else if (name.equals("cube")) {
anim = new CubeAnimation(c, attrs);
} else {
throw new RuntimeException(
"not a cubeanimation animation name: "
+ parser.getName());
}
}
if (parent != null) {
parent.addAnimation(anim);
} return anim; }
}
配置文件加载和动态构造两种方式创建对话实例以及调用
public class AnimateActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_main);
View view = this.findViewById(R.id.tv);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Animation animation;
if(v.getTag()==null||(Boolean)v.getTag()){
((TextView)v).setText("配置文件加载");
animation = CubeAnimation.loadAnimation(getApplicationContext(), R.anim.cubeanimation);
v.setTag(false);
}else{
((TextView)v).setText("动态初始化");
animation = new CubeAnimation(0, 400, 0, 360, 100);
animation.setDuration(8000);
v.setTag(true);
}
v.startAnimation(animation);
}
}); }
}
ok 基本完成,希望没有什么遗漏
android自定义动画的更多相关文章
- android 自定义动画
android自定义动画注意是继承Animation,重写里面的initialize和applyTransformation,在initialize方法做一些初始化的工作,在applyTransfor ...
- [原创]android自定义动画的一点感悟
android提供了一系列的动画处理api,包括animator以及animation等.由于动画效果是根据人眼视觉残留原理形成的,因此动画过程中android需要不断频繁的更新view的相关属性,由 ...
- Android 自定义动画 Loading
转自:http://my.oschina.net/janson2013/blog/118558 1.定义一个ImageView 定义一个ImageView是为了装载图片,其中的图片将被rotate用来 ...
- Android为TV端助力 自定义动画
android自定义动画注意是继承Animation,重写里面的initialize和applyTransformation,在initialize方法做一些初始化的工作,在applyTransfor ...
- Android 自定义属性动画&Camera动画
摘要: Android 自定义属性动画&Camera动画 1.相关知识点 对于Androi的帧动画,可以制作gif图片,有时为了能够动态的生成帧动画,就得需要使用代码构建了 Animati ...
- Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析
这是关于RecyclerView的第二篇,说的是如何自定义Item动画,但是请注意,本文不包含动画的具体实现方法,只是告诉大家如何去自定义动画,如何去参考源代码. 我们知道,RecyclerView默 ...
- Android自定义View 画弧形,文字,并增加动画效果
一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类 B ...
- Android 自定义波浪动画 --"让进度浪起来~"
原文链接:http://www.jianshu.com/p/0e25a10cb9f5 一款效果不错的动画,实现也挺简单的,推荐阅读学习~ -- 由 傻小孩b 分享 waveview <Andro ...
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这里我简单说明一下用自定义ViewGroup来实现. 实现方法:我们自定义一个ViewGroup实现左右滑动, ...
随机推荐
- MarkDown---超强文本编辑器
What you see Is What you get ... --------------------------- Salmon 编辑器界面: ------------------------ ...
- 语音激活检测(VAD)--前向神经网络方法(Alex)
这是学习时的笔记,包含相关资料链接,有的当时没有细看,记录下来在需要的时候回顾. 有些较混乱的部分,后续会再更新. 欢迎感兴趣的小伙伴一起讨论,跪求大神指点~ VAD(ffnn神经网络)-Alex t ...
- 关于request、response转发与重定向的简述
在做页面的请求与响应的时候我们多用request与response进行操作,而我们大家也知道,request是表示用户发向服务器的请求,而response是对用户请求的一个响应. 关于转发和重定向,通 ...
- .NET 自定义Json序列化时间格式
.NET 自定义Json序列化时间格式 Intro 和 JAVA 项目组对接,他们的接口返回的数据是一个json字符串,里面的时间有的是Unix时间戳,有的是string类型,有的还是空,默认序列化规 ...
- DispatcherTimer和Timer(计时器)
System.Windows.Threading.DispatcherTimer dTime; System.Timers.Timer timer; public Main ...
- Ext.grid.EditorGridPanel分页刷新
store.reload(); var start = grid.getBottomToolbar().cursor;//获取当前页开始条数 上面获取当前页第一条记录的方法有时候说未定义,我现在使用下 ...
- 消息摘要技术(MD5)
1.使用消息摘要技术对密码加密 数据库存储的是经过消息摘要技术加密之后的信息, 避免保存密码明文,提升了系统安全性 必要性说明: 如果存储明文密码,数据库系统管理员和攻破系统的黑客是可以拿到你的所有信 ...
- SpirngMVC入门第一天
SpringMVC第一天 1. 计划 第一天 1.SpringMVC介绍 2.入门程序 3.SpringMVC架构讲解 a ...
- 编译安装LAMP并实现wordpress
author:JevonWei 版权声明:原创作品 软件环境 centos7.3 apr-1.5.2.tar.bz2 apr-util-1.5.4.tar.bz2 httpd-2.4.27.tar.b ...
- 自动化测试:behave
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...