【问题标题】:How to use SurfaceView to overlay another SurfaceView and why canvas be null?如何使用 SurfaceView 覆盖另一个 SurfaceView 以及为什么画布为空?
【发布时间】:2016-01-27 06:35:04
【问题描述】:

我正在尝试使用SurfaceViewCanvas 来绘制波形。我正在使用一个SurfaceViewCanvas 进行绘图,它可以工作。

但是当我想让我的第一个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);
    }

}

我已经困惑了两个星期,希望有人可以帮助我解决这个问题。 谢谢大家。

【问题讨论】:

    标签: android virtual-machine android-canvas surfaceview


    【解决方案1】:

    首先,请记住,SurfaceView 有两个部分,即 Surface 和 View。 View 部分的行为与任何其他 View 一样。 Surface 是异步创建的,是一个完全独立的层。

    您当前的代码正在创建两个具有相同 Z 顺序的重叠 Surface,这意味着它们试图同时占据相同的空间。结果未定义,但一般来说,您会看到一个 Surface 而不是另一个。使用例如setZOrderMediaOverlay() 应该在另一个前面。有关三个重叠 Surface 的示例,请参阅Grafika's“多表面测试”活动。

    Surface 是异步创建的,而不是同时创建的,因此您应该期望您的 surfaceCreated() 回调会触发两次。看起来您每次都在打电话给init()。如果它首先为 Surface A 触发,并且init() 尝试在 Surface B 上绘图,则该方法将失败,因为它试图在尚未创建的 Surface 上绘图。检查surfaceCreated() 中SurfaceHolder 的值,并且只在刚刚创建的Surface 上绘制。 (或者,等到它们都被创建后,然后在两者上绘制。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-09
      相关资源
      最近更新 更多