2016-01-27 76 views
1

我試圖使用SurfaceViewCanvas來繪製波形。我使用一個SurfaceViewCanvas來繪製,並且它可以工作。如何使用SurfaceView疊加另一個SurfaceView以及爲什麼畫布爲空?

但是,當我想使第一個SurfaceView覆蓋第二個SurfaceView(使用FrameLayout)。這是行不通的。

而且這兩個問題,在我看來:

1. If I use Canvas in second SurfaceView, then the second canvas becomes null; 

    2. If I don't use Canvas in second SurfaceView, but just call overlay, then the SurfaceView size will be overlay but the graph is same. 

引用代碼如下:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Log.e("onCreate", "here"); 
    l1 = (LinearLayout) findViewById(R.id.l1); 
    l2 = (LinearLayout) findViewById(R.id.l2); 
    l2.setVisibility(View.INVISIBLE); 
    sfv = (SurfaceView) findViewById(R.id.sfv); 
    sfh = sfv.getHolder(); 
    sfv.getHolder().setFormat(PixelFormat.TRANSLUCENT); 


    sfv2 = (SurfaceView) findViewById(R.id.sfv2); 
    sfh2 = sfv2.getHolder(); 
    sfv2.getHolder().setFormat(PixelFormat.TRANSLUCENT); 

    paint.setColor(Color.BLUE); 
    paint.setStrokeWidth(3); 
    paint2.setColor(Color.RED); 
    paint2.setStrokeWidth(3); 
    Log.i("flow", "now at before init()"); 
    tv = (TextView) findViewById(R.id.tv); 
    sfh.addCallback(this); 
    sfh2.addCallback(this); 
    //init(); 
} 

public void init() { 
    Log.e("init", "here"); 
    if (pic) { 
     canvas = sfh.lockCanvas(new Rect(xtime, 0, xtime + 2, getWindowManager().getDefaultDisplay().getHeight())); 
     canvas.drawARGB(255, 0, 0, 0); 
     for (int i = 0; i < 600; i++) { 
      a = 600 - i; 
      canvas.drawLine(xtime, oldy, xtime + 2, a, paint); 
      xtime += 2; 
      oldy = a; 
      if (xtime > 1000) { 
       xtime = 0; 
       oldy = 0; 
      } 
     } 
     sfh.unlockCanvasAndPost(canvas); 
     // tv.setText("in the init2"); 
    } 
    else{ 
     Log.e("sfh2", "here"); 
     canvas = sfh2.lockCanvas(new Rect(xtime2, 0, xtime2 + 2, getWindowManager().getDefaultDisplay().getHeight())); 
     if(canvas == null){ 
      Log.e("canvas", "null here"); 
     } 
     else { 
      canvas.drawARGB(255, 255, 255, 255); 
      for (int i = 0; i < 300; i++) { 
       a = 300 - i; 
       canvas.drawLine(xtime2, oldy, xtime2 + 2, a, paint2); 
       xtime2 += 2; 
       oldy = a; 
       if (xtime2 > 1000) { 
        xtime2 = 0; 
        oldy2 = 0; 
       } 
      } 
      sfh2.unlockCanvasAndPost(canvas); 
     } 
    } 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    Log.e("surfaceCreated", "here"); 
    init(); 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    Log.e("surfaceChanged", "here"); 
    init(); 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    Log.e("surfaceDestroyed", "here"); 

} 

public void onchange(View view) { 
    if (pic) { 
     pic = false; 
     l1.setVisibility(View.VISIBLE); 
     l2.setVisibility(View.INVISIBLE); 
     tv.setText("change sf2"); 
     Log.e("pic", "pic " + pic); 
    } else { 
     pic = true; 
     l1.setVisibility(View.INVISIBLE); 
     l2.setVisibility(View.VISIBLE); 
     tv.setText("change sf1"); 
     Log.e("pic", "pic " + pic); 
    } 

} 

我一直在混淆了兩個星期,希望有人可以幫我解決這個問題。 謝謝大家。

回答

0

首先,最重要的是,請記住SurfaceView有兩部分,Surface和View。 View部分的行爲與其他View類似。 Surface是異步創建的,並且是一個完全獨立的圖層。

您當前的代碼創建兩個具有相同Z排序的重疊曲面,這意味着它們試圖同時佔用相同的空間。結果是不確定的,但一般來說,你會看到一個表面,而不是另一個表面。使用例如setZOrderMediaOverlay()應該在另一個之前。有關三個重疊曲面的示例,請參見Grafika's「多表面測試」活動。

表面是異步創建的,而不是同時創建,因此您應該期望您的回調觸發兩次。看起來你每次都打電話給init()。如果它首先觸發Surface A,並且init()試圖在Surface B上繪圖,則該方法將失敗,因爲它試圖繪製尚未創建的Surface。檢查surfaceCreated()中的SurfaceHolder的值,並且只繪製剛創建的Surface。 (或者,等到它們都被創建,然後同時使用)。