首先普及一下动画的实现原理:动画其实是多张照片不断切换形成的动态变化图,单位为帧。我们可以在一段时间间隔内不断绘制view来实现动画效果。在每次重绘中,改变view的相关属性和位置即可。
这里我们也会用到Thread多线程,指的是程序中的子任务的顺序流。程序在执行过程中会有一个主线程和若干从属线程,主线程好比是外科主任,子线程就可以比做是助理的角色。
这里面我们做的是绘制一个笑脸在屏幕里自由反弹的动态图。会直线连我们已经知道,接下来是让他们动起来。
private void drawBou(Canvas canvas)
{
float w=canvas.getWidth();
float h=canvas.getHeight();
Paint redp=new Paint();
redp.setARGB(255,255,0,0);
redp.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawOval(ballx,bally,ballx+30,bally+30,redp);//由X,Y点坐标1确定的图形在不断变化中
//face
Paint yellow = new Paint();
yellow.setARGB(255, 255, 255, 0);
yellow.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawOval(100+ballx, 100+bally, ballx+300, 300+bally, yellow);
//eyes
Paint blue=new Paint();
blue.setARGB(255,0,0,255);
canvas.drawOval(140+ballx,140+bally,170+ballx,170+bally,blue);
canvas.drawOval(230+ballx,140+bally,260+ballx,170+bally,blue);
//nose
Paint blac=new Paint();
blac.setARGB(255,0,0,0);
blac.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawOval(190+ballx,180+bally,210+ballx,200+bally,blac);
//mouth
Paint red=new Paint();
red.setARGB(255,255,0,0);
red.setStyle(Paint.Style.FILL);
canvas.drawRect(170+ballx,230+bally,230+ballx,250+bally,red);
ballx+=vex;
bally+=vey;
if(ballx+ballsize>=w||ballx<=0) //当图形碰撞到手机的左右界面是,X方向速度相反
{
vex=-vex;
}
if(bally+ballsize>=h||bally<=0) //当图形碰撞到手机的上下界面是,y方向相反
{
vey=-vey;
}
}
接下来我们还会用到一个函数进行重新绘制 dothe();
public void dothe() {
while (true)
{
try {
Thread.sleep(1);
} catch (InterruptedException e)
{
e.printStackTrace();
}
postInvalidate();
}
}
Thread.sleep(1)函数指的是线性程序休息一毫秒在继续工作。由此在每秒钟可以绘画1000张图片。
postinvalidate()指的是执行主线程程序。
public void moveclick(View view)
{
final faceview facevie=(faceview)findViewById(R.id.myfaceview);
// facevie.postInvalidate();
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
facevie.dothe();
}
});
thread.start();
}
直接调用facevie.dothe()函数是错误的。应为主线程在执行该函数的过程中,对其它子线程就不再响应了。所以应该创建一个子线程,将该函数放到子线程中去执行。
执行后的效果动态图如下所示。