?????? 在线程动画中,要用到线程,然而线程不方便直接访问界面上的组件,需要用到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(){ }}
?
?