当前位置: 代码迷 >> Android >> Android 作图线程动画
  详细解决方案

Android 作图线程动画

热度:94   发布时间:2016-04-28 04:26:43.0
Android 绘制线程动画

?????? 在线程动画中,要用到线程,然而线程不方便直接访问界面上的组件,需要用到SurfaceView间接去访问界面上的组件。SurfaceView需要继承SurfaceHolder.Callback接口,在该接口中有三个方法:

	//当surfaceview被创建时调用	public void surfaceCreated(SurfaceHolder holder) {				}         //当横竖屏幕切换时调用	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {			}	//当surfaceview 被销毁时调用	public void surfaceDestroyed(SurfaceHolder holder) {	}

?下面是小球运动的线程代码:

????????? activity_main.xml文件主要设计组件:

?

?

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/container"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.example.surface.MainActivity"    tools:ignore="MergeRootFrame" >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal" >        <Button            android:id="@+id/button1"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="0.20"            android:onClick="found"            android:text="@string/text_add" />        <Button            android:id="@+id/button2"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="0.39"            android:onClick="found"            android:text="@string/pause" />        <Button            android:id="@+id/button3"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="0.31"            android:onClick="found"            android:text="@string/resume" />        <Button            android:id="@+id/button4"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="0.33"            android:onClick="found"            android:text="@string/stop" />    </LinearLayout>    <com.example.surface.MySurfaceView        android:id="@+id/mySurfaceView1"        android:layout_width="match_parent"        android:layout_height="match_parent" /></LinearLayout>

?

???????? 在MainActivity.java主要是设计界面图层和实现按钮监听器的方法:

?

?

?

package com.example.surface;import android.app.Activity;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity {		private MySurfaceView mv;	protected void onCreate(Bundle savedInstanceState) {		//调用父类中的onCreate方法		super.onCreate(savedInstanceState);		//设置界面图层		setContentView(R.layout.activity_main);				//根据id地址找到mySurfaceView对象		mv=(MySurfaceView)findViewById(R.id.mySurfaceView1);				}	 	//实现给按钮添加监听器的方法		public void found(View v){			//根据id地址判断那一个按钮			if(v.getId() == R.id.button1){				System.out.println("======");				mv.addBall();			}			if(v.getId() == R.id.button2){				     Data.setPauseflag(true);			}			if(v.getId() == R.id.button3){				   Data.setPauseflag(false);			}			if(v.getId() == R.id.button4){				while(!Data.list.isEmpty()){					Ball ba = Data.list.remove(0);				}			}		}}

?

????????? 在MySurfaceView.java主要实现线程间接访问界面组件:

package com.example.surface;import android.content.Context;import android.util.AttributeSet;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;public class MySurfaceView extends SurfaceView implements Callback{		private SurfaceHolder holder;	private DrawThread dt;	//带一个参数的构造方法,并调用带两个参数的构造方法	public MySurfaceView(Context context) {		this(context, null);	}		//带两个参数的构造方法,并调用带三个参数的构造方法	public MySurfaceView(Context context, AttributeSet attrs) {		this(context, attrs, 0);	}	//带三个参数的构造方法,并继承父类中的方法	public MySurfaceView(Context context, AttributeSet attrs, int defStyle) {		super(context, attrs, defStyle);		//获取画布		holder = this.getHolder();		//回调方法		holder.addCallback(this);		//		setFocusable(true);	}		//当surfaceview被创建时调用	public void surfaceCreated(SurfaceHolder holder) {				System.out.println("surfaceCreated");				//创建线程对象,并开始线程		dt = new DrawThread(this,holder);	    dt.start();			}	//当横竖屏幕切换时调用	public void surfaceChanged(SurfaceHolder holder, int format, int width,			int height) {		System.out.println("surfaceChanged");			}	//当surfaceview 被销毁时结束线程	public void surfaceDestroyed(SurfaceHolder holder) {		System.out.println("surfaceDestroyed");		//结束线程		dt.setRunflag(false);	}		//添加小球的方法	public void addBall(){		Ball ball = new Ball(this);	    Data.list.add(ball);	}}

?

????? 在DrawThread.java类中继承Thread,实现run方法:

package com.example.surface;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.view.SurfaceHolder;public class DrawThread extends Thread{	private SurfaceHolder holder;	private boolean runFlag=true;	private Paint paint = new Paint();	private Canvas canvas;	private MySurfaceView mv;		public DrawThread(MySurfaceView mv, SurfaceHolder holder){		this.mv = mv;		this.holder = holder;	}		//便于在其它类里面获取runFlag	public void setRunflag(boolean runFlag) {		this.runFlag = runFlag;	}		//线程中的run方法	public void run(){		while(runFlag){			try {				Thread.sleep(40);			} catch (InterruptedException e) {				e.printStackTrace();			}			//获取Surfaceview上的画布对象,并且锁定						if(Data.pauseflag){				continue;			}			try {				canvas = holder.lockCanvas();				//画的风格设为填充式、颜色为白色				paint.setStyle(Style.FILL);				paint.setColor(Color.WHITE);				//用长方形填充一下背景				canvas.drawRect(0, 0, mv.getWidth(), mv.getHeight(), paint);				//遍历队列				for(int i=0; i<Data.list.size(); i++){					Ball e = Data.list.get(i);					e.draw(canvas);					e.move();				}			} catch (Exception e) {				e.printStackTrace();			}finally{				if(canvas != null){					//画布对象使用完成后,必须要释放					holder.unlockCanvasAndPost(canvas);				}			}											}			}}

?

??? 在Data.java中主要存一些项目中经常用到的数据:

?

package com.example.surface;import java.util.ArrayList;public class Data {	public static ArrayList<Ball> list = new ArrayList<Ball>();	public static boolean pauseflag = false;		//便于在其它类里面获取pauseflag	public static void setPauseflag(boolean pauseflag) {		Data.pauseflag = pauseflag;	}	}

?

?????? 在Ball.java中主要实现小球的绘画与运动:

?

package com.example.surface;import java.util.Random;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;public class Ball extends Entity{	private float x, y, vx, vy, radius;		private MySurfaceView mv;			public Ball(MySurfaceView mv){		this.mv = mv;				inint();	}		//初始化一些参数	public void inint(){		//创建随机对象,让小球的移动速度与半径随机生成		Random r = new Random();		vx = r.nextInt(5)+5;		vy = r.nextInt(5)+5;		radius = r.nextInt(20)+20;	}	//画小球的方法	public void draw(Canvas c){		Paint paint = new Paint();		paint.setColor(Color.GREEN);		c.drawCircle(x, y, radius, paint);	}		//小球移动的方法	public void move(){    	x+=vx;    	y+=vy;    	if(x<=0){    		vx=5;    	}if(x>=mv.getWidth()-radius){    		vx=-5;    	}if(y<=0){    		vy=5;    	}if(y>=mv.getHeight()-radius){    		vy=-5;    	}	}}

?

????? Entity.java一些绘画图片的父类:

?

?

?

package com.example.surface;import android.graphics.Canvas;public class Entity {		public void draw(Canvas c){			}	public void move(){			}}

?

?

  相关解决方案