前面說到了畫圖,其實更好的就是使用 surfaceView了。
surfaceView 繼承於 View,View里面嵌套了一個專門用於畫圖的 surface,
對於一個View的onDraw()方法,不能夠滿足將其移動到后台線程中去。因為從后台線程修改一個GUI元素會被顯式地禁止的。當需要快速地更新View的UI,或者當前渲染代碼阻塞GUI線程的時間過長的時候,SurfaceView就是解決上述問題的最佳選擇。SurfaceView封裝了一個Surface對象,而不是Canvas。這一點很重要,因為Surface可以使用后台線程繪制。對於那些資源敏感的操作,或者那些要求快速更新或者高速幀率的地方,例如使用3D圖形,創建游戲,或者實時預覽攝像頭,這一點特別有用。
可以直接從內存或硬件設備比如相機等取得圖像數據,是個非常重要的繪圖容器。它的特性是:可以在主線程之外的線程中向屏幕繪圖。這樣可以避免畫圖任務繁重的時候造成主線程阻塞,從而提高了程序的反應速度。繪制的東西直接復制到顯存從而顯示出來,這使得顯示速度會非常快,而在Surface 被銷毀之前必須結束。
下面給個簡單的例子,就是不停的繪制 ,這樣按照前面說的,就可以再 上面繪制各種自己想要的效果了:
- public class SurfaceDraw extends Activity{
- private SurfaceView sf;
- private SurfaceHolder sfh; //surfaceView的 控制器
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_draw);
- sf = (SurfaceView) this.findViewById(R.id.SurfaceView01);
- //得到控制器
- sfh = sf.getHolder();
- //對 surfaceView 進行操作
- sfh.addCallback(new DoThings());// 自動運行surfaceCreated以及surfaceChanged
- }
- private class DoThings implements SurfaceHolder.Callback{
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- //在surface的大小發生改變時激發
- System.out.println("surfaceChanged");
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder){
- new Thread(){
- public void run() {
- while(true){
- //1.這里就是核心了, 得到畫布 ,然后在你的畫布上畫出要顯示的內容
- Canvas c = sfh.lockCanvas(new Rect(0, 0, 200, 200));
- //2.開畫
- Paint p =new Paint();
- p.setColor(Color.rgb( (int)(Math.random() * 255),
- (int)(Math.random() * 255) , (int)(Math.random() * 255)));
- Rect aa = new Rect( (int)(Math.random() * 100) ,
- (int)(Math.random() * 100)
- ,(int)(Math.random() * 500)
- ,(int)(Math.random() * 500) );
- c.drawRect(aa, p);
- //3. 解鎖畫布 更新提交屏幕顯示內容
- sfh.unlockCanvasAndPost(c);
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- }
- }
- };
- }.start();
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- //銷毀時激發,一般在這里將畫圖的線程停止、釋放。
- System.out.println("surfaceDestroyed==");
- }
- }
- }
// 實現拖拽效果,也就是動態的繪制
- public class Drag extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- DragImage view=new DragImage(this);
- setContentView(view);
- }
- private class DragImage extends SurfaceView implements SurfaceHolder.Callback,Runnable,OnTouchListener{
- private Context context;
- private SurfaceHolder holder;
- private Bitmap icon;
- private Paint paint;
- private boolean running=true;
- public DragImage(Context context) {
- super(context);
- this.context=context;
- holder = this.getHolder();//獲取holder
- holder.addCallback(this);
- this.setOnTouchListener(this);
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- icon = BitmapFactory.decodeResource(context.getResources(),R.drawable.wuranl_1);
- paint=new Paint();
- running=true;
- new Thread(this).start();
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- running=false;
- }
- @Override
- public void run() {
- int SLEEP_TIME=100;
- while (running) {
- //開始畫的時間 long start=System.currentTimeMillis();
- Canvas canvas = holder.lockCanvas();//獲取畫布
- canvas.drawColor(Color.BLACK);
- canvas.drawBitmap(icon, rect.left,rect.top,null);
- holder.unlockCanvasAndPost(canvas);// 解鎖畫布,提交畫好的圖像
- //結束的時間 long end=System.currentTimeMillis();
- }
- }
- // Region region=new Region();
- private Point point=new Point();//點擊點
- private Rect rect;//圖片的rect
- private boolean canDrag=false;//判斷是否點擊在圖片上,否則拖動無效
- private int offsetX=0,offsetY=0;//點擊點離圖片左上角的距離
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- // TODO Auto-generated method stub
- switch (event.getAction()) {
- //手按下的時候
- case MotionEvent.ACTION_DOWN:
- point.x=(int)event.getX();
- point.y=(int)event.getY();
- if(rect.contains(point.x, point.y)){
- canDrag=true;
- offsetX=point.x-rect.left;
- offsetY=point.y-rect.top;
- }
- break;
- //移動的時候
- case MotionEvent.ACTION_MOVE:
- if(canDrag){
- rect.left=(int)event.getX()-offsetX;
- rect.top=(int)event.getY()-offsetY;
- rect.right=rect.left+icon.getWidth();
- rect.bottom=rect.top+icon.getHeight();
- if (rect.left < 0) {
- rect.left = 0;
- rect.right = rect.left+icon.getWidth();
- }
- if (rect.right > getMeasuredWidth()) {
- rect.right = getMeasuredWidth();
- rect.left = rect.right-icon.getWidth();
- }
- if (rect.top < 0) {
- rect.top = 0;
- rect.bottom = rect.top+icon.getHeight();
- }
- if (rect.bottom > getMeasuredHeight()) {
- rect.bottom = getMeasuredHeight();
- rect.top = rect.bottom-icon.getHeight();
- }
- }
- break;
- case MotionEvent.ACTION_UP:
- canDrag=false;
- break;
- default:
- break;
- }
- return true;
- }
- }
- }
還有前面在 View上面繪制的動態折線圖,在surfaceView上效果也更好呢