`
fddong123456
  • 浏览: 6715 次
社区版块
存档分类
最新评论

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(){
		
	}
}

 

 

分享到:
评论

相关推荐

    Android App中使用SurfaceView制作多线程动画的实例讲解

    通常情况程序的View和用户响应都是在同一个线程中处理的,这也是为什么处理长时间事件(例如访问网络)需要放到另外的线程中去(防止阻塞当前UI线程的操作和绘制)。但是在其他线程中却不能修改UI元素,例如用后台...

    Android中TextureView与SurfaceView用法区别总结

    与其它View不同的是,两者都能在独立的线程中绘制和渲染,在专用的GPU线程中大大提高渲染的性能。 一、SurfaceView专门提供了嵌入视图层级的绘制界面,开发者可以控制该界面像Size等的形式,能保证界面在屏幕上的...

    Android利用SurfaceView实现下雨的天气动画效果

    可以看到效果图中的雨滴的下落速度很快,那么意味着每一帧都要调用 onDraw() 一次使其重新绘制一次,假如你的 onDraw() 方法里面的渲染代码稍微有点费时,而 View 的 onDraw() 方法调用是在 UI 线程中,那么绘制出

    Android绘制动态折线图

    所谓动态折线图,就是折线图能随着手指的滑动进行动态绘制,这里很定会产生动画效果。基于这个效果,这里使用SurfaceView进行制图。 实现步奏如下: (1): 这里新建一个绘图ChartView,继承SurfaceView并实现...

    android开发揭秘PDF

    前言 第一部分 准备篇 第1章 Android开发简介 ...14.4.2 流程控制和线程 14.4.3 游戏对象与对象管理 14.4.4 图形引擎 14.4.5 物理引擎 14.4.6 事件模块 14.4.7 工具模块 14.4.8 脚本引擎、音效模块、网络 模块

    Android开发艺术探索.任玉刚(带详细书签).pdf

    第7章 Android动画深入分析 265 7.1 View动画 265 7.1.1 View动画的种类 265 7.1.2 自定义View动画 270 7.1.3 帧动画 272 7.2 View动画的特殊使用场景 273 7.2.1 LayoutAnimation 273 7.2.2 Activity的切换...

    Android开发艺术探索

    第7章 Android动画深入分析 / 265 7.1 View动画 / 265 7.1.1 View动画的种类 / 265 7.1.2 自定义View动画 / 270 7.1.3 帧动画 / 272 7.2 View动画的特殊使用场景 / 273 7.2.1 LayoutAnimation / 273 ...

    Android-低内存消耗的序列帧动画库只占用一张序列帧图片的内存可用于直播大礼物的展示

    低内存消耗的序列帧库,只占用了一张序列帧图片的内存,异步绘制不占用UI线程资源,同时复用序列帧Bitmap,减少内存抖动,避免了频繁的GC,提高动画的流畅性。可用于直播大礼物的展示。

    Android UI组件实例集合

    1、Android显示GIF动画 GifView GifView 是一个为了解决android中现在没有直接显示gif的view,只能通过mediaplay来显示这个问题的项目,其用法和 ImageView一样,支持gif图片 使用方法:1-把GifView.jar加入你的项目...

    Android 创建GifFrame 解析GIF动画显示GIF图片.rar

    Android 解析GIF动画显示GIF图片,使用线程得到当前帧的图片,绘制当前帧的图片,保存gif中所有帧的向量,创建GifFrame ,最终将一幅GIF图像显示在android设备界面中。本例测试运行的效果,如截图示,一个动态的GIF...

    《Android应用开发揭秘》附带光盘代码.

     14.4.2 流程控制和线程  14.4.3 游戏对象与对象管理  14.4.4 图形引擎  14.4.5 物理引擎  14.4.6 事件模块  14.4.7 工具模块  14.4.8 脚本引擎、音效模块、网络  模块  14.5 小结  第15章 优化技术  ...

    android mp3歌词滚动效果实现

    在UI线程中另起线程,通过回调函数 onDraw() 每隔100ms重新绘制屏幕,实现歌词平滑滚动的动画效果。 运行程序前,先在SDCard根目录下新建LyricSync目录,将 歌曲和歌词.zip 中的 1.mp3 和 1.lrc 文件解压放入...

    Android应用开发揭秘pdf高清版

    14.4.2 流程控制和线程 14.4.3 游戏对象与对象管理 14.4.4 图形引擎 14.4.5 物理引擎 14.4.6 事件模块 14.4.7 工具模块 14.4.8 脚本引擎、音效模块、网络 模块 14.5 小结 第15章 优化技术 15.1 优化的基本知识 ...

    android-openGL-canvas:一个Android库,提供使用openGL画布在SurfaceView或TextureView上绘制内容的视图

    另外,因为使用OpenGL在另一线程渲染,所以里面的GLContinuousView还提供能够实现高效的动画的方法。(如果只是这个功能不要其他得话,那么我建议你直接继承View,见)与GPU图片对比:提供无限循环渲染线程的...

    《Android应用开发揭秘》源码

     14.4.2 流程控制和线程  14.4.3 游戏对象与对象管理  14.4.4 图形引擎  14.4.5 物理引擎  14.4.6 事件模块  14.4.7 工具模块  14.4.8 脚本引擎、音效模块、网络模块  14.5 小结  第15章 优化技术  15.1 ...

    android开发艺术探索高清完整版PDF

    / 484 14.4 JNI调用Java方法的流程 / 486 第15章 Android性能优化 / 489 15.1 Android的性能优化方法 / 490 15.1.1 布局优化 / 490 15.1.2 绘制优化 / 493 15.1.3 内存泄露优化 / 493 15.1.4 响应速度优化和...

    精通ANDROID 3(中文版)1/2

    13.1 Android组件和线程  13.1.1 活动在主线程上运行  13.1.2 广播接收程序在主线程上运行  13.1.3 服务在主线程上运行  13.1.4 ContentProvider在主线程上运行  13.1.5 单一主线程的影响  13.1.6 ...

Global site tag (gtag.js) - Google Analytics