文字动画(Textdh)
首先,这个文字动画是自己从app里面抽取出来的一个dome。主要与大家学习与交流。
1. Donghua.java这个类实现了各种动画的类,自己把它封装了起来,以便大家使用。里面代码也不复杂,大家可以研究下。
原理是在不同时刻传入t的不同而获取不同的Matrix而在画板画上位图。Matrix是重点,里面所有的动画全部调用Matrix的方法实现不同位图的变形与变换。多种简单动画的叠加从而生成复杂的动画。
package com.youxianwubian.textdh.textdh; import android.graphics.*; /* 有限无边 time:2016.1.16_11:25 */ public class Donghua { Matrix mat; private int pw,ph;//操作位图的宽,高 private int hb_w; private int hb_h; private float zx_x;//位图在画布中心时的x,y坐标。 private float zx_y; boolean fd_x,fd_y,sx_x,sx_y,xz,wyr_x,wyr_y,wyl_x,wyl_y,qx_x,qx_y; private int xz_st=180,xz_sp=0; private float x,y; public Donghua() { if(mat==null) { mat=new Matrix(); } } public void setFd_x(boolean fd_x) { this.fd_x = fd_x; } public boolean isFd_x() { return fd_x; } public void setFd_y(boolean fd_y) { this.fd_y = fd_y; } public boolean isFd_y() { return fd_y; } public void setSx_x(boolean sx_x) { this.sx_x = sx_x; } public boolean isSx_x() { return sx_x; } public void setSx_y(boolean sx_y) { this.sx_y = sx_y; } public boolean isSx_y() { return sx_y; } public void setXz(boolean xz) { this.xz = xz; } public boolean isXz() { return xz; } public void setWyr_x(boolean wyr_x) { this.wyr_x = wyr_x; } public boolean isWyr_x() { return wyr_x; } public void setWyr_y(boolean wyr_y) { this.wyr_y = wyr_y; } public boolean isWyr_y() { return wyr_y; } public void setWyl_x(boolean wyl_x) { this.wyl_x = wyl_x; } public boolean isWyl_x() { return wyl_x; } public void setWyl_y(boolean wyl_y) { this.wyl_y = wyl_y; } public boolean isWyl_y() { return wyl_y; } public void setQx_x(boolean qx_x) { this.qx_x = qx_x; } public boolean isQx_x() { return qx_x; } public void setQx_y(boolean qx_y) { this.qx_y = qx_y; } public boolean isQx_y() { return qx_y; } /* @i:第一个参数为动画类型 @t:第二个参数为动画的状态 范围0-1f */ public Matrix getmat(float t) { /*if(t<0) {t=0;} if(t>1) {t=1;}*/ setmatdz(t); return mat; } //设置动画属性 public void setdonghuasx(int i,boolean b) { switch (i){ case 0: setFd_x(b); break; case 1: setFd_y(b); break; case 2: setSx_x(b); break; case 3: setSx_y(b); break; case 4: setWyr_x(b); break; case 5: setWyr_y(b); break; case 6: setWyl_x(b); break; case 7: setWyl_y(b); break; case 8: setQx_x(b); break; case 9: setQx_y(b); break; case 10: setXz(b); break; } setcswz(); } private void setmatdz(float t) { setxzwz(); if(t>=0) { //位移向右x if(wyr_x) { dhwyr_x(t); } //位移向右y if(wyr_y) { dhwyr_y(t); } //位移向左x if(wyl_x) { dhwyl_x(t); } //位移向左y if(wyl_y) { dhwyl_y(t); } //setcswz(); //setxzwz(); //放大动画x if(fd_x) { dhfd_x(t); } //放大动画y if(fd_y) { dhfd_y(t); } //缩小动画x if(sx_x) { dhsx_x(t); } //缩小动画y if(sx_y) { dhsx_y(t); } //x轴倾斜 if(qx_x) { dhqx_x(t); } //y轴倾斜 if(qx_y) { dhqx_y(t); } //旋转 if(xz) { dhxz(xz_st,xz_sp,t); } } else {setcswz();} //iscshwz(t); } //设置画布w,h设置位图w,h public void sethb_wh(int w,int h,int pw,int ph) { this.pw=pw; this.ph=ph; hb_w=w; hb_h=h; zx_x=(float)hb_w/2-(float)pw/2; zx_y=(float)hb_h/2-(float)ph/2; x_y(zx_x,zx_y); x=zx_x; y=zx_y; } //操作位图平移 public void x_y(float xb,float yb) { mat.postTranslate(xb,yb); } //设置文字初始位置 private void setcswz() { mat.setTranslate(zx_x,zx_y); x=zx_x; y=zx_y; } private void setxzwz() { mat.setTranslate(x,y); } //判断t为1时初始化位置 private void iscshwz(float t) { if(t==1f) setcswz(); } //从无限小放大到原图包含x.y private void dhfd_x(float t) { mat.postScale(t,1,(float)hb_w/2,(float)hb_h/2); } private void dhfd_y(float t) { mat.postScale(1,t,(float)hb_w/2,(float)hb_h/2); } //从2倍大小缩小为原图 private void dhsx_x(float t) { float tb=2.0f-t; mat.postScale(tb,1,(float)hb_w/2,(float)hb_h/2); } private void dhsx_y(float t) { float tb=2.0f-t; mat.postScale(1,tb,(float)hb_w/2,(float)hb_h/2); } /* @st:起始角度 @sp:结束角度 @t :动画状态 */ private void dhxz(int st,int sp,float t) { float tb=(1.0f-t)*(st-sp)+sp; mat.postRotate(tb,(float)hb_w/2,(float)hb_h/2); } //位移动画 从0变到中心 右动画 private void dhwyr_x(float t) { float tb=zx_x*t/2; x=tb; x_y(tb,0); } private void dhwyr_y(float t) { float tb=zx_y*t/2; y=tb; x_y(0,tb); } //位移动画 从边界变到中心 左动画 private void dhwyl_x(float t) { //float tb=((float)hb_w-(float)pw/2); float tb=((float)hb_w-(float)pw)/2-(((float)hb_w-(float)pw)-zx_x)*t/2; //float tb=zx_x*2; x=tb; x_y(tb,0); } private void dhwyl_y(float t) { //float tb=(hb_h-ph)-(hb_h-ph-zx_y)*t; float tb=((float)hb_h-(float)ph)/2-(((float)hb_h-(float)ph)-zx_y)*t/2; y=tb; x_y(0,tb); } //倾斜 private void dhqx_x(float t) { float tb=1 - t; mat.postSkew(tb, 0, (float)hb_w / 2, (float)hb_h / 2); } private void dhqx_y(float t) { float tb=1 - t; mat.postSkew(0,tb,(float)hb_w/2,(float)hb_h/2); } }
2.ylview.java 这个类是自定义的View,继承自View主要实现了动画的显示控件。
里面利用计时器开启一个线程间隔30毫秒使int t参数增加1 然后调用 invalidate();刷新界面画图,画图使调用Donghua类的getmat((float)t/100)获取
Matrix来画现在时刻的位图。
package com.youxianwubian.textdh.textdh; import android.content.*; import android.graphics.*; import android.os.*; import android.view.*; import android.widget.*; import java.util.*; public class ylview extends View { private int mHeight; private int mWidth; private Bitmap bit; private Paint paint; private Donghua donghua; private int t; private Context con; private Handler //获取数据,,并显示! myHandler = new Handler() { @Override public void handleMessage(Message msg) { //如果该消息是本程序所发送的 if (msg.what == 0) { invalidate(); } } }; private MyTimerTask task=null ; private Timer timer = new Timer(true); class MyTimerTask extends TimerTask { @Override public void run() { // TODO Auto-generated method stub t++; if(t>100) { t=-20; } Message msg = new Message(); msg.what = 0; //发送消息 myHandler.sendMessage(msg); /* if(task==null) { task=new MyTimerTask(); } timer.schedule(task,0, Qjbl.jgtime); //延时1000ms后执行,1000ms执行一次 timer.cancel(); //退出计时器 timer=null; timer = new Timer(true); task=null; */ } } public ylview(Context context, int height, int width) { super(context); this.mHeight = height - 36; this.mWidth = width; setMinimumHeight(height - 36); setMinimumWidth(width); paint=new Paint(); donghua=new Donghua(); this.con=context; } @Override protected void onDraw(Canvas canvas) { if(bit!=null) { canvas.drawBitmap(bit, donghua.getmat((float)t/100), paint); //图片 } //addt(); /* if(this.t>100) { this.t=0; //Toast.makeText(con, "超过1"+this.t, Toast.LENGTH_SHORT).show(); }*/ //postInvalidateDelayed(1000); // Toast.makeText(con, "t为:"+this.t, Toast.LENGTH_SHORT).show(); super.onDraw(canvas); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(mWidth, mHeight); } public void setbit(Bitmap bit) { this.bit=bit; donghua.sethb_wh(mWidth,mHeight,bit.getWidth(),bit.getHeight()); //invalidate(); startrun(); } public Donghua getdonghua() { return donghua; } public void settime() { t=0; //Toast.makeText(con, "设置刷新"+t, Toast.LENGTH_SHORT).show(); //invalidate(); } public void startrun() { if(task==null) { task=new MyTimerTask(); } timer.schedule(task,0, 30); //延时1000ms后执行,1000ms执行一次 } public void stoprun() { timer.cancel(); //退出计时器 timer=null; timer = new Timer(true); task=null; } }
项目运行截图:
代码下载:http://download.youkuaiyun.com/detail/zhangjie1425/9410671