您的位置:首页 > 移动开发 > Android开发

Android学习之surfaceview(一)

2014-10-05 10:38 246 查看
今天在学习Android游戏开发中的crazy football中遇到了一些问题。首先碰到的就是surfaceview相关的知识,由于之前没有接触过图像渲染方面的东西,觉得理解起来不太容易。因此专门将这个知识点拿出来学习一下。

       学习surfaceview之前,肯定有必要先了解一下view的基本知识。其实简单理解view就是每个activity界面的显示效果。系统自带了很多种效果,例如各种各样的布局文件,就是其中的很多种效果。我们也可以自己定义自己的效果。最简单的就是我们新建一个画布,在画布上绘制我们自己想要看的东西。这也是一种显示效果。不过自己定义的view有一个致命的缺点,它的参数更改只能在UI线程中进行。若要执行的任务比较消耗时间,就会导致UI线程长期的等待,从而程序死掉。下面是一个简单的自定义view代码:

 

 

[java] view
plaincopy

package com.example.test;  

  

  

import android.app.Activity;  

import android.content.Context;  

import android.graphics.Canvas;  

import android.graphics.Color;  

import android.graphics.Paint;  

import android.os.Bundle;  

import android.view.View;  

  

     public class AnimateViewActivity extends Activity {     

           

           

         protected void onCreate(Bundle savedInstanceState) {     

             super.onCreate(savedInstanceState);     

          

          setContentView(new AnimateView(this));//這邊傳入的this代表這個對象,  

            // setContentView(new DemoSurfaceView(this));//這邊傳入的this代表這個對象,  

//  因 為Activity是繼承自Content類的,因此該對象也      

//                                                  可向上轉型為Content類型作為   

  

//  AnimateView的構造方法的參數    

          }    

         

         class AnimateView extends View{     

           

             float radius = 10;             

             Canvas canvas=new Canvas();  

             Paint paint=new Paint(); ;     

               

           

             public AnimateView(Context context) {    

                 super(context);    

                     

                paint.setColor(Color.RED);     

                 paint.setStyle(Paint.Style.FILL_AND_STROKE);    

                 //onDraw(canvas);  

            }    

             

             @Override      

             protected void onDraw(Canvas canvas) {    

            

                 canvas.translate(200, 200);     

                 canvas.drawCircle(80, 80, radius++, paint);              

         

                    if(radius > 100){    

                      radius = 10;    

                  }   

                    

                   invalidate();//通过调用这个方法让系统自动刷新视图          

             }    

          

         }    

          

      }  

这段代码实现了不断更新圆圈半径的显示。改变的过程是通过ondraw方法中的invalidate()方法实现的。
 
下面来看看surfaceview的使用方法:
      讲到surfaceVIEW,就得先提到与其相关联的其他几个名词:1,surface,2,surfaceholder,3 callback()
首先来解释一下,surface其实就是一块内存区域,代表了一块显存。surfaceholder可以管理控制surfaceview,比如说控制画布canvas等
callback()函数管理了surface生命周期的三个主要函数,oncreat,onchange,ondestroy.
     使用的基本方法:
 1,创建类继承surfaceview 并实现callback接口
 2,初始化init,包括得到surfaceholder,(getholder()方法得到),利用holder来添加回调函数callback()
 3,   新建一个线程,来处理生命周期中所需要处理的动作(可选)
4, 在生命周期函数中,不断结束线程和开始线程,具体由动作决定(停止线程join()).
下面是一段实例代码:(只需要在上一段代码中添加这一句,并注释上一句就行// setContentView(new DemoSurfaceView(this));//這邊傳入的this代表這個對象,)
 

[java] view
plaincopy

    package com.example.test;    

         

    import android.content.Context;    

    import android.graphics.Canvas;    

    import android.graphics.Color;    

    import android.graphics.Paint;    

    import android.view.SurfaceHolder;    

    import android.view.SurfaceHolder.Callback;    

    import android.view.SurfaceView;    

         

    public class DemoSurfaceView extends SurfaceView  implements Callback{    

         

        LoopThread thread;    

         

        public DemoSurfaceView(Context context) {    

            super(context);    

         

            init(); //初始化,设置生命周期回调方法    

         

        }    

         

        private void init(){    

         

            SurfaceHolder holder = getHolder();    

            holder.addCallback(this); //设置Surface生命周期回调    

            thread = new LoopThread(holder, getContext());    

        }    

         

        @Override    

        public void surfaceChanged(SurfaceHolder holder, int format, int width,    

                int height) {    

        }    

         

        @Override    

        public void surfaceCreated(SurfaceHolder holder) {    

            thread.isRunning = true;    

            thread.start();    

        }    

         

        @Override    

        public void surfaceDestroyed(SurfaceHolder holder) {    

            thread.isRunning = false;    

            try {    

                thread.join();    

            } catch (InterruptedException e) {    

                e.printStackTrace();    

            }    

        }    

         

        /**  

         * 执行绘制的绘制线程  

         * @author Administrator  

         *  

         */    

        class LoopThread extends Thread{    

         

            SurfaceHolder surfaceHolder;    

            Context context;    

            boolean isRunning;    

            float radius = 10f;    

            Paint paint;    

         

            public LoopThread(SurfaceHolder surfaceHolder,Context context){    

         

                this.surfaceHolder = surfaceHolder;    

                this.context = context;    

                isRunning = false;    

         

                paint = new Paint();    

                paint.setColor(Color.YELLOW);   

                paint.setTextSize(100);  

                paint.setStyle(Paint.Style.STROKE);    

            }    

         

            @Override    

            public void run() {    

         

                Canvas c = null;    

         

                while(isRunning){    

         

                    try{    

                        synchronized (surfaceHolder) {    

         

                            c = surfaceHolder.lockCanvas(null);    

                            doDraw(c);    

                            //通过它来控制帧数执行一次绘制后休息50ms    

                            Thread.sleep(50);    

                        }    

                    } catch (InterruptedException e) {    

                        e.printStackTrace();    

                    } finally {    

                        surfaceHolder.unlockCanvasAndPost(c);    

                    }    

         

                }    

         

            }    

         

            public void doDraw(Canvas c){    

         

                //这个很重要,清屏操作,清楚掉上次绘制的残留图像    

                c.drawColor(Color.BLACK);    

         

                c.translate(200, 200);    

                c.rotate(30);  

//              c.drawCircle(200,200, radius++, paint);    

                c.drawText("hello"+radius++, 50, 50, paint);  

         

                if(radius > 100){    

                    radius = 10f;    

                }    

         

            }    

         

        }    

         

    }    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息