画在bitmap上可以这么设置canvas

Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);

画在View上 (On a View)

如果你的应用不许需要大量处理帧,也不需要高的帧处理速率,比如下棋游戏,蛇吃豆游戏,动画都比较慢的这类。考虑创建一个View,然后在 View.onDraw()中用canvas画图。这样android框架会给你提供一个预先定义的Canvas,代替你自己来调用画图函数。 Android框架有必要的时候才会调用onDraw函数,每次你的应用准备要画图的时候,让那个View调用 invalidate(),然后android框架会调用onDraw函数,但不保证立刻调用。

Note: 从线程中调用 invalidate,而不是在Main Activity的线程中调用,必须要调用postInvalidate().

 

1、继承View的class

public final class LyricView extends View {
	public LyricView(Context context) {
		super(context);
	}

	/**
	 * 重绘视图
	 */
	@Override
	protected void onDraw(Canvas c) {
		super.onDraw(c);
		
		Paint pText = new Paint(); //画笔
		pText.setColor(Color.GRAY);
		pText.setTextSize(10);
		pText.setAntiAlias(true); //消除锯齿
		c.drawText("my draw!", 0, 0, pText);		
	  //画图片 
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);  
    c.drawBitmap(bitmap, 250,360, p);
	}
}


2、在界面的xml中添加一个layoutView,用来放置画图的LyricView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <LinearLayout
        android:id="@+id/lyoutView"
        android:layout_width="fill_parent"
        android:orientation="vertical" 
        android:layout_height="150dp"
        android:layout_weight="2" >
</LinearLayout> 
</LinearLayout>


3、在Activity中

public class Mp3PlayerActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.mp3player);

		
		// 用LinearLayout存放画图的View
		LinearLayout layout = (LinearLayout) findViewById(R.id.lyoutView);
		vwLrc = new LyricView(layout.getContext());
		layout.addView(vwLrc);
		}
}




On a SurfaceView 用surfaceView画图

SurfaceView是View的子类,提供了画图的surface。目的是为了给应用的第二个线程提供画图surface,这样就不需要等待系统的View准备好画图,相反,引用了SurfaceView的第二个线程可以按自己的节奏画图。

开始使用surfaceview,创建一个继承SurfaceView的类,这个类也必须implement SurfaceHolder.Callback 通过SurfaceHolder来处理surface对象,当你的surfaceView初始化的时候,通过getHolder()获取SurfaceHolder ,然后再调用addCallback() 把surfaceHolder传递给它,然后重载你surfaceView类的surfaceHolder.Callback的所有方法。 为了在你第二个线程中使用canvas,你必须传递线程到你的SurfaceHolder,通过lockCanvas()获取Canvas,然后你就可以用Canvas来画图了,用完之后,调用unlockCanvasAndPost()并传递Canvas对象参数。

http://blog.csdn.net/kongbaidepao/article/details/15028099

surfaceView 继承于 View,View里面嵌套了一个专门用于画图的 surface, 对于一个View的onDraw()方法,不能够满足将其移动到后台线程中去。因为从后台线程修改一个GUI元素会被显式地禁止的。

当需要快速地更新View的UI,或者当前渲染代码阻塞GUI线程的时间过长的时候,SurfaceView就是解决上述问题的最佳选择。SurfaceView封装了一个Surface对象,而不是Canvas。这一点很重要,因为Surface可以使用后台线程绘制。对于那些资源敏感的操作,或者那些要求快速更新或者高速帧率的地方,例如使用3D图形,创建游戏,或者实时预览摄像头,这一点特别有用。 可以直接从内存或硬件设备比如相机等取得图像数据,是个非常重要的绘图容器。它的特性是:可以在主线程之外的线程中向屏幕绘图。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。绘制的东西直接复制到显存从而显示出来,这使得显示速度会非常快,而在Surface 被销毁之前必须结束。

下面给个简单的例子,就是不停的绘制 ,这样按照前面说的,就可以再 上面绘制各种自己想要的效果了:

 

1、layout.activity_draw .xml中添加surfaceView控件

 

2、Activity中代码:

 

Note: On each pass you retrieve the Canvas from the SurfaceHolder, the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the entire surface. For example, you can clear the previous state of the Canvas by filling in a color with drawColor() or setting a background image with drawBitmap(). Otherwise, you will see traces of the drawings you previously performed.

画新图的时候,上次画得图还会保留,如果不想保留上次的画图,通过Canvas的drawColor()或者DrawBitmap()就可以清空上次的状态,重新画整个surface。

 

上面的方式使用了控件,不用surfaceview控件,直接按照官方说明进行画图,如下:

代码来自这里


1、      创建一个绘制线程如下

2、      自定义一个SurfaceView类如下:

3、      主Activity修改view

 



分类: Android

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注