SurfaceView 之俄羅斯方塊、打飛機、遙感賽車

https://www.jianshu.com/p/91e9fee635c1

SurfaceView

  • SurfaceView可以直接在子線程中更新ui,顯示畫面流暢。

  • 因爲SurfaceView提供雙緩衝機制。通過兩個線程交替在兩塊內存緩衝區繪製畫面。

  • 直接繪製不通過點擊(直接在activity的oncreate方法中調用要創建監聽器,只有surfaceview創建後才能創建畫布,不能在surfaceview沒準備好就直接創建)

  • SurfaceView在繪製前要先鎖定畫布(獲取畫布),繪製完成後對畫布解鎖,把畫布的內容顯示到屏幕上

  • SurfaceHolder保持了surfaceView的對象,所以它管理着生命週期

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

      // 1.查找控件
      SurfaceView sv = (SurfaceView) findViewById(R.id.sv);
    
      // 2.獲得控制器
      holder = sv.getHolder();
    

    }

    public void draw(View v) {

      for (int i = 0; i < 100; i++) {
    
          // 繪製一個半徑變大圓
          // 3.鎖定畫布
          Canvas lockCanvas = holder.lockCanvas();
          
          //清除上一幀內容
          lockCanvas.drawColor(Color.BLACK);
    
          Paint paint = new Paint();
          paint.setColor(Color.RED);
    
          // 利用畫布對象繪製 圓心x,y座標 半徑 畫筆對象
          lockCanvas.drawCircle(120, 120, 5 + i, paint);
    
          // 5.解鎖並提交
          holder.unlockCanvasAndPost(lockCanvas);
      }
    

    }

import android.view.SurfaceHolder.Callback; 注意導包

    // 1.查找控件
    SurfaceView sv = (SurfaceView) findViewById(R.id.sv);

    // 2.獲得控制器
    holder = sv.getHolder();
    
    //設置監聽器,當surface創建時,再繪製
    holder.addCallback(new Callback() {
        
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // TODO Auto-generated method stub
            System.out.println("當界面不可見時,surfaceDestroyed被調用了");
        }
        
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // TODO Auto-generated method stub
            System.out.println("當界面可見時,surfaceCreated被調用了");
            myDraw();
        }
        
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
            // TODO Auto-generated method stub
            System.out.println("當Surface尺寸或格式時變化,surfaceChanged被調用了");
        }
    });
  • draw是一個耗時不確定的方法,每次繪製耗費時間不同可能會顯示卡頓,一直draw對性能也會有影響,所以最好有延時操作

    /**

    • 繪製的主線程
      */
      @Override
      public void run() {
      while (isThreadFlag) {
      long start = System.currentTimeMillis();
      try {
      synchronized (CartSurfaceView.class) {
      mCanvas = mSurfaceHolder.lockCanvas(); //

           }
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           if (mCanvas != null) {
              mSurfaceHolder.unlockCanvasAndPost(mCanvas);//結束鎖定畫圖,並提交改變。
           }
       }
       long end = System.currentTimeMillis();
       // 讓線程休息100毫秒
       if (end - start < 30) {
           try {
               Thread.sleep(30 - (end - start));
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
      

      }

    }
    SurfaceView小遊戲之俄羅斯方塊(kotlin)

    SurfaceView小遊戲之打飛機(kotlin)

    遙感賽車

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章