Android Surface View绘图API详解

本文详细介绍了Android中视图绘制的基本原理与实践技巧,包括单个及多个图形的绘制、混合图形的组合与动态效果实现。通过具体示例,展示了如何利用SurfaceView、Canvas等组件完成复杂的图形绘制任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一)绘制单个图形

surfaceHolder是surface控制器,通过它来控制图层图形的大小像素等

锁定画布和解锁画布是必须要进行的操作

draw()绘制方法的调用必须在surfaceView创建之后,在surfaceViewDestroy()之前

package com.example.myview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MyView extends SurfaceView implements SurfaceHolder.Callback{

	
	private Paint paint;
	
	public MyView(Context context) {
	   super(context);
	   paint=new Paint();
	   paint.setColor(Color.BLUE);
	   getHolder().addCallback(this);
	}

	public void draw(){
		Canvas canvas=getHolder().lockCanvas(); //锁定画布
		canvas.drawColor(Color.WHITE);
		canvas.drawRect(0, 0,100,100,paint);
        getHolder().unlockCanvasAndPost(canvas);  //解锁画布
	}
	
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		draw();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		
	}

}






二)绘制多个图形,在绘制方法里同时绘制即可,比如下面画两条线

	public void draw(){
		Canvas canvas=getHolder().lockCanvas(); //锁定画布
		canvas.drawColor(Color.WHITE);
        canvas.drawLine(0, getHeight()/2,getWidth(), getHeight(), paint);	
        canvas.drawLine(0, getHeight()/2+100,getWidth()/2+100, getHeight(), paint);
        getHolder().unlockCanvasAndPost(canvas);  //解锁画布
	}
	


如果我们想修改,比如旋转较长的那条线,需要先调用画布的save()方法,然后进行修改,之后调用restore()

public void draw(){
		Canvas canvas=getHolder().lockCanvas(); //锁定画布
		canvas.drawColor(Color.WHITE);
		canvas.save();
		canvas.rotate(90, getWidth()/2, getHeight()/2);
        canvas.drawLine(0, getHeight()/2,getWidth(), getHeight(), paint);
        canvas.restore();
        canvas.drawLine(0, getHeight()/2+100,getWidth()/2+100, getHeight(), paint);
        getHolder().unlockCanvasAndPost(canvas);  //解锁画布
	}
	


三)绘制混合图形

绘制组合图形,创建一个容器,在容器里创建一个list集合来存放所有的子图形,子图形又可以嵌套别的图形,从而实现组合的效果。

将集合放在构造方法里,并且封装一个add方法来将一个子容器放进容器里,还有remove方法。

draw()来使用遍历的方法对所有的容器绘制画布。

注意childrenView()里面的画布,遍历绘制还有实体图形绘制的时候用的都是这里的画布,这是容器的画布。

1)新建容器

package com.example.myview;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import android.graphics.Canvas;

public class Contanier {

	private List<Contanier> children=null;
	public Contanier(){
		children=new ArrayList<Contanier>();
	}
	public void draw(Canvas canvas){
		childrenView(canvas);
		for(Contanier c:children){
			c.draw(canvas);
		}
	}
	public void childrenView(Canvas canvas){
		
	}
	public void addChildrenView(Contanier child){
		children.add(child);
	}
	public void removeChildrenVeiw(Contanier child){
		children.remove(child);
	}
	
}

2)绘制实体图形

矩形

package com.example.myview;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

public class Rect extends Contanier{

	private Paint paint=null;
	public Rect(){
		paint=new Paint();
		paint.setColor(Color.RED);
	}
	
	@Override
	public void childrenView(Canvas canvas) {
       super.childrenView(canvas);
       canvas.drawRect(0, 0, 100, 100, paint);
		
	}
}

圆形

package com.example.myview;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

public class Circle extends Contanier{

	
	private Paint paint=null;
	public  Circle(){
		paint=new Paint();
		paint.setColor(Color.BLUE);
	}
	
	@Override
	public void childrenView(Canvas canvas) {
       super.childrenView(canvas);
       canvas.drawCircle(50, 50, 50, paint);
	}
}

3)在MyView()里面进行容器的绘制操作

public class MyView extends SurfaceView implements SurfaceHolder.Callback{

	
	private Contanier contanier;
	private Rect rect;
	private Circle circle;
	
	public MyView(Context context){
		super(context);
		contanier=new Contanier();
		rect=new Rect();
		circle=new Circle();
		rect.addChildrenView(circle); //圆放在矩形里
		contanier.addChildrenView(rect); //矩形放在容器里
		getHolder().addCallback(this);
	}

	public void draw(){
		Canvas canvas=getHolder().lockCanvas(); //锁定画布
		canvas.drawColor(Color.WHITE);
		contanier.draw(canvas);//绘制容器
        getHolder().unlockCanvasAndPost(canvas);  //解锁画布
	}
	



四)给混合图形添加移动效果,以上面的混合图形为例

1)在Contanier类里,translate()方法来移动,设置x,y的值和get(),set()

	private float x=0,y=0;
	
	public Contanier(){
		children=new ArrayList<Contanier>();
	}
	public void draw(Canvas canvas){
		canvas.save();
		canvas.translate(getX(),getY());
		childrenView(canvas);
		for(Contanier c:children){
			c.draw(canvas);
		}
		canvas.restore();
	}
	
	
	public void childrenView(Canvas canvas){
		
	}
	public void addChildrenView(Contanier child){
		children.add(child);
	}
	public void removeChildrenVeiw(Contanier child){
		children.remove(child);
	}
	public float getX() {
		return x;
	}
	public void setX(float x) {
		this.x = x;
	}
	public float getY() {
		return y;
	}
	public void setY(float y) {
		this.y = y;
	}
	


2)在Rect类里的childrenView()加一行,在y轴上移动一个像素

 this.setY(getY()+1)

3)在MyView()里写一个时间任务,每0.1s就执行一次绘制过程
	private  Timer timer=null;
    private  TimerTask  timerTask=null;
    
    public void startTimer(){
    	timer=new Timer();
    	timerTask=new TimerTask() {
			
			@Override
			public void run() {
				draw();		
			}
		};
		timer.schedule(timerTask, 100,100); //从100毫秒开始,每100毫秒执行一次
    }
    
    
    public void stopTimer(){
    	if(timer!=null){
    		timerTask.cancel();
    		timer=null;
    	}
    	
    	
    }
	
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		startTimer();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		stopTimer();
	}

这样,混合图形就会顺着y轴向下移动,每0.1s移动一次

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值