前一篇说了实现过程,这次来写一个自己简单实现的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自定义动画的更多相关文章

  1. android 自定义动画

    android自定义动画注意是继承Animation,重写里面的initialize和applyTransformation,在initialize方法做一些初始化的工作,在applyTransfor ...

  2. [原创]android自定义动画的一点感悟

    android提供了一系列的动画处理api,包括animator以及animation等.由于动画效果是根据人眼视觉残留原理形成的,因此动画过程中android需要不断频繁的更新view的相关属性,由 ...

  3. Android 自定义动画 Loading

    转自:http://my.oschina.net/janson2013/blog/118558 1.定义一个ImageView 定义一个ImageView是为了装载图片,其中的图片将被rotate用来 ...

  4. Android为TV端助力 自定义动画

    android自定义动画注意是继承Animation,重写里面的initialize和applyTransformation,在initialize方法做一些初始化的工作,在applyTransfor ...

  5. Android 自定义属性动画&Camera动画

      摘要: Android 自定义属性动画&Camera动画 1.相关知识点 对于Androi的帧动画,可以制作gif图片,有时为了能够动态的生成帧动画,就得需要使用代码构建了 Animati ...

  6. Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析

    这是关于RecyclerView的第二篇,说的是如何自定义Item动画,但是请注意,本文不包含动画的具体实现方法,只是告诉大家如何去自定义动画,如何去参考源代码. 我们知道,RecyclerView默 ...

  7. Android自定义View 画弧形,文字,并增加动画效果

    一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类   B ...

  8. Android 自定义波浪动画 --"让进度浪起来~"

    原文链接:http://www.jianshu.com/p/0e25a10cb9f5 一款效果不错的动画,实现也挺简单的,推荐阅读学习~ -- 由 傻小孩b 分享 waveview <Andro ...

  9. android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu

    示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这里我简单说明一下用自定义ViewGroup来实现. 实现方法:我们自定义一个ViewGroup实现左右滑动, ...

随机推荐

  1. CentOS7下搭建hadoop2.7.3完全分布式

    这里搭建的是3个节点的完全分布式,即1个nameNode,2个dataNode,分别如下: CentOS-master   nameNode   192.168.11.128 CentOS-node1 ...

  2. 7.21.03 while循环和do...while循环

    while循环 while是最基本的循环,它的结构为: while( 布尔表达式 ) { //循环内容 } 只要布尔表达式为true,循环体会一直执行下去. 有时程序也需要死循环. 实例 public ...

  3. 权限大全-linux基础

    一.文件权限 (1)文件的权限主要针对三类对象定义: u:属主,owner    g:属组,group    o:其他,other    权限有三种:    r:可读    w:可写    x:可执行 ...

  4. Struts2.5 利用Ajax将json数据传值到JSP

    AJAX +JSON=>JSP AJAX AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着 ...

  5. 又一流氓推广Microsoft Edge,我勒个去

    最新的Windows10 的升级也是醉了,不得不吐槽一个非常流氓的浏览器推广:Microsoft Edge(这小婊砸). 为了将之前的历史包袱IE干掉,这次微软也是蛮拼的,直接把IE从电脑里干掉了,你 ...

  6. firebird常用语句

    分页写法小例 SELECT FIRST templateid,code,name FROM template ; SELECT FIRST SKIP templateid,code,name FROM ...

  7. HTML+CSS画一朵向日葵

    前几天看到一张图片,倔强的向日葵.(BGM,<倔强>) 看着挺有感触,就想用CSS做一个向日葵. 最终效果图如下: 主要的难点就在花瓣的处理上,css暂时没有做到这样的尖角圆弧. 我想到的 ...

  8. 代码精简之Lombok

    JavaWeb项目开发中,JavaBean总是不可避免的出现,随之而来的就是大量的getter.setter方法,虽然大部分的开发工具(比如Eclipse等)都支持自动生成这些东西,但是一旦Bean里 ...

  9. union-find算法Java实现

    package practice; /*在一个全是点的图中,循环选择两点连通,之后判断两点是否在同一通路*/ public class Testmain { public static void ma ...

  10. 快速排序Java实现

    package practice; import edu.princeton.cs.algs4.*; public class TestMain { public static void main(S ...