【问题标题】:Set the Background Image of a SurfaceView设置 SurfaceView 的背景图片
【发布时间】:2011-08-24 06:40:08
【问题描述】:

有没有办法设置 SurfaceView 的背景图像?它必须在 xml 中完成还是我可以在 Java 中完成 - 我的构造函数中有一些看起来像这样的东西:

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

但它仍然没有显示任何内容。

【问题讨论】:

    标签: java android background-image drawable surfaceview


    【解决方案1】:

    虽然您不能直接将背景图像设置为SurfaceView,但您可以将ImageView(显示背景图像)和SurfaceView 重叠在此之上,使其透明。

    在为每个 SurfaceView 重绘绘制 1920x1080 位图作为背景图像时,我遇到了性能问题:我找到的唯一解决方案(感谢 this answer)是使用 ImageView 显示此 1920x1080(固定)位图,并使用我的SurfaceView 在上面,使其透明,避免为每个SurfaceView 重新绘制大背景图像。现在我的应用程序更加流畅了,这要归功于这段代码:

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

    然后你应该用这个来开始你的SurfaceView的paint方法:(为了“刷新”SurfaceView的缓冲区中之前绘制的图像)

    canvas.drawColor(0, PorterDuff.Mode.CLEAR);
    

    【讨论】:

    • 谢谢你! 2天我试图做到这一点! 5 年后,这仍然挽救了某人的生命。
    • 非常感谢...canvas.drawColor(0, PorterDuff.Mode.CLEAR); 是关键!
    【解决方案2】:

    试试这个

    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
    }
    

    【讨论】:

    • 如何将布局大小赋予画布上的位图绘图,并将其放置在表面视图的中心。
    【解决方案3】:

    您不能在 SurfaceView 上设置背景可绘制对象。您必须自己在表面上绘制背景。

    【讨论】:

    • 好的,所以我想在 onDraw() 方法中?
    • 不,onDraw() 不会做你想做的事。当您使用 SurfaceView 时,您可以使用 OpenGL 上下文渲染到其中,或者通过 SurfaceHolder 获取表面的画布。您必须使用该画布(如果您正在使用 OpenGL,则使用 OpenGL)渲染您的背景。
    • 我只使用 Canvas - 我只是想弄清楚如何使用 Canvas 做到这一点。
    • 嗨,如何将图像放在画布上和表面视图的中心
    • 虽然从技术上讲这个答案是正确的,但下面的@xav 答案提供了很好的替代方案,可以实现 OP 的要求。
    【解决方案4】:
    your surfaceView.setBackground(getResources().getDrawable(R.drawable.?));
    

    【讨论】:

      【解决方案5】:

      xav 对答案的一个小补充。之后您希望将内容视图设置为 rootPanel:

      setContentView(rootPanel);
      

      此外,由于 FILL_PARENT 已被弃用,请考虑在这两个地方使用 MATCH_PARENT。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2020-11-21
        • 2015-05-09
        • 2012-03-07
        • 2020-07-03
        相关资源
        最近更新 更多