Set the Background Image of a SurfaceView

谁都会走 提交于 2019-11-29 04:28:06

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

Try this

public void surfaceCreated(SurfaceHolder arg0) {
    Bitmap background = BitmapFactory.decodeResource(getResources(), R.drawable.background);
    float scale = (float)background.getHeight()/(float)getHeight();
    int newWidth = Math.round(background.getWidth()/scale);
    int newHeight = Math.round(background.getHeight()/scale);
    Bitmap scaled = Bitmap.createScaledBitmap(background, newWidth, newHeight, true);
}

public void onDraw(Canvas canvas) {
    canvas.drawBitmap(scaled, 0, 0, null); // draw the background
}
xav

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);

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.

your surfaceView.setBackground(getResources().getDrawable(R.drawable.?));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!