前一篇说了实现过程,这次来写一个自己简单实现的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. 【Linux】查看进程号

    1.查看占用8080端口的进程号 lsof -i: | awk '{print $2}' | uniq | grep -P -o "[0-9]{2,5}" 2.查看使用java进程 ...

  2. 你所不知道的 CSS 动画技巧与细节

    怕标题起的有点大,下述技巧如果你已经掌握了看看就好,欢迎斧正,本文希望通过介绍一些 CSS 不太常用的技巧,辅以一些实践,让读者可以更加深入的理解掌握 CSS 动画. 废话少说,直接进入正题,本文提到 ...

  3. 获取windows所有用户名

    #include <LM.h> #pragma comment(lib, "netapi32.lib") // See more: http://msdn.micros ...

  4. C/C++遍历文件夹和文件

    本方法可用于windows和linux双平台,采用C/C++标准库函数. 库函数 包含头文件 #include 用到数据结构_finddata_t,文件信息结构体的指针. struct _findda ...

  5. CodeForces 432C Prime Swaps

    Description You have an array a[1], a[2], ..., a[n], containing distinct integers from 1 to n. Your ...

  6. Java后台开发必备软件(windows环境下)

    一.必备软件 1.Jdk,推荐下载最新版2.Ide,推荐 IntelliJ IDEA3.服务器,如 tomcat / jetty4.数据库终端界面,推荐 Navicat Premium(自行破解),5 ...

  7. jQuery方法输出有几个checkbox框被选中

    每选中一个多选框,输出有多少个选中 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  8. Mybatis映射文件完整模板参照

    Mybatis映射文件完整模板参照 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE map ...

  9. Stylus-NodeJS下构建更富表现力/动态/健壮的CSS

    --------------------------本文来自张鑫旭大神博客------------------------------ 一.为什么我会讲Stylus,而不是SASS和LESS? SAS ...

  10. Java数据库连接池比较(c3p0,dbcp,proxool和BoneCP)

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp21 Java框架数据库连接池比较(c3p0,dbcp和proxool,Bo ...