8

Is there a way to set the background image of a SurfaceView? Does it have to be done in xml or can I do it all in Java - I've got something that looks like this in my constructor:

Drawable sky = (getResources().getDrawable(R.drawable.sky));
    this.setBackgroundDrawable(sky);

But it still doesn't show anything.

Hani Honey
  • 2,101
  • 11
  • 48
  • 76

4 Answers4

11

While you can't directly set a background image to a SurfaceView, you can overlap an ImageView (displaying your background image) and your SurfaceView on top of this, making it transparent.

I had performances issues when drawing a 1920x1080 bitmap as a background image for each SurfaceView repaint: the only solution I found (thanks to this answer) was using an ImageView displaying this 1920x1080 (fixed) bitmap, and using my SurfaceView on top of it, making it transparent, to avoid painting the big background image for each SurfaceView repaint. Now my app is much smoother, thanks to this code:

// Setup your SurfaceView
SurfaceView surfaceView = ...;  // use any SurfaceView you want
surfaceView.setZOrderOnTop(true);
surfaceView.getHolder().setFormat(PixelFormat.TRANSPARENT);

// Setup your ImageView
ImageView bgImagePanel = new ImageView(context);
bgImagePanel.setBackgroundResource(...); // use any Bitmap or BitmapDrawable you want

// Use a RelativeLayout to overlap both SurfaceView and ImageView
RelativeLayout.LayoutParams fillParentLayout = new RelativeLayout.LayoutParams(
    RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
RelativeLayout rootPanel = new RelativeLayout(context);
rootPanel.setLayoutParams(fillParentLayout);
rootPanel.addView(surfaceView, fillParentLayout); 
rootPanel.addView(bgImagePanel, fillParentLayout); 

Then you shall start your SurfaceView's paint method with this: (in order to "flush" the previous drawn image in SurfaceView's buffer)

canvas.drawColor(0, PorterDuff.Mode.CLEAR);
Community
  • 1
  • 1
xav
  • 5,452
  • 7
  • 48
  • 57
4

You cannot set a background drawable on a SurfaceView. You'll have to draw the background onto the surface yourself.

Romain Guy
  • 97,993
  • 18
  • 219
  • 200
  • Okay, so in the onDraw() method I would presume? – Hani Honey May 12 '11 at 16:28
  • No, onDraw() will not do what you want. When you use a SurfaceView you either render into it using an OpenGL context or you grab the surface's Canvas through the SurfaceHolder. You must render your background using that Canvas (or OpenGL if you are doing OpenGL.) – Romain Guy May 12 '11 at 16:30
  • 1
    I'm only using a Canvas - I'm just trying to figure out how I would do that with the Canvas. – Hani Honey May 12 '11 at 16:31
  • hi how to fit the image on canvas and at the centre of the surfaceview – Sunishtha Singh Apr 30 '15 at 04:30
  • Although technically this answer is correct, @xav answer below provides good alternative which achieves what OP had asked. – yajnesh Apr 13 '21 at 15:55
2
your surfaceView.setBackground(getResources().getDrawable(R.drawable.?));
mohammad
  • 47
  • 3
0

A small addition to the answer by xav. You'd want to set the content view as rootPanel afterwards:

setContentView(rootPanel);

Also, since FILL_PARENT is deprecated, consider using MATCH_PARENT in both places.

Sergey Emeliyanov
  • 5,158
  • 6
  • 29
  • 52