You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调整Bitmap图片大小使其适配Android游戏界面屏幕

Android自定义View Bitmap适配屏幕解决方案

核心问题原因

直接加载原始尺寸Bitmap绘制,未根据View的实际显示尺寸做缩放,1920*1080的原图在小尺寸屏幕上会超出显示边界。

调整步骤

  • 重写onSizeChanged方法获取View的最终宽高,不要在构造函数中获取尺寸,此时View还未完成测量无法拿到正确值
  • 在onSizeChanged中完成所有Bitmap的缩放操作,该方法只会在尺寸变化时执行一次,避免在onDraw中重复计算影响性能
  • 绘制坐标建议和View宽高绑定,避免不同屏幕下元素位置偏移

完整修改代码

public class PoliceView extends View {

    private Bitmap police;
    private Bitmap scaledPolice; // 缩放后的警车图
    private Bitmap background;
    private Bitmap scaledBackground; // 缩放后的背景图
    private Paint scorePaint = new Paint();
    private Bitmap life[] = new Bitmap[2];
    private Bitmap scaledLife[] = new Bitmap[2]; // 缩放后的生命值图标

    // 存储View的实际宽高
    private int viewWidth;
    private int viewHeight;

    public PoliceView(Context context) {
        super(context);

        police = BitmapFactory.decodeResource(getResources(),R.drawable.police);
        background = BitmapFactory.decodeResource(getResources(),R.drawable.gamebackground);
        

        scorePaint.setColor(Color.BLACK);
        scorePaint.setTextSize(70);
        scorePaint.setTypeface(Typeface.DEFAULT_BOLD);
        scorePaint.setAntiAlias(true);

        life[0] = BitmapFactory.decodeResource(getResources(),R.drawable.heart);
        life[1] = BitmapFactory.decodeResource(getResources(),R.drawable.brokenheart);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        viewWidth = w;
        viewHeight = h;

        // 缩放背景图,直接铺满整个View
        scaledBackground = Bitmap.createScaledBitmap(background, viewWidth, viewHeight, true);

        // 缩放警车图标,比例可自行调整
        float policeScale = 0.25f;
        int policeWidth = (int) (police.getWidth() * policeScale);
        int policeHeight = (int) (police.getHeight() * policeScale);
        scaledPolice = Bitmap.createScaledBitmap(police, policeWidth, policeHeight, true);

        // 缩放生命值图标,比例可自行调整
        float lifeScale = 0.15f;
        int lifeWidth = (int) (life[0].getWidth() * lifeScale);
        int lifeHeight = (int) (life[0].getHeight() * lifeScale);
        scaledLife[0] = Bitmap.createScaledBitmap(life[0], lifeWidth, lifeHeight, true);
        scaledLife[1] = Bitmap.createScaledBitmap(life[1], lifeWidth, lifeHeight, true);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //绘制顺序十分重要,元素会按照该顺序依次渲染
        canvas.drawBitmap(scaledBackground,0,0,null);
        canvas.drawBitmap(scaledPolice, 0, 0, null);
        canvas.drawText("Score:",20, 60, scorePaint);
        //玩家共有3点生命值,坐标和屏幕宽度绑定适配不同设备
        int lifeStartX = viewWidth - 300;
        canvas.drawBitmap(scaledLife[0],lifeStartX, 10, null);
        canvas.drawBitmap(scaledLife[0],lifeStartX + 100, 10, null);
        canvas.drawBitmap(scaledLife[0],lifeStartX + 200, 10, null);
    }
}

可选优化(保持图片宽高比不拉伸)

如果需要避免图片拉伸变形,可以按如下逻辑计算等比缩放比例:

// 示例:背景图等比铺满View
float widthScale = (float) viewWidth / background.getWidth();
float heightScale = (float) viewHeight / background.getHeight();
// 取较大的缩放比例保证背景铺满View,超出部分会被裁剪
float finalScale = Math.max(widthScale, heightScale);
int finalBgWidth = (int) (background.getWidth() * finalScale);
int finalBgHeight = (int) (background.getHeight() * finalScale);
scaledBackground = Bitmap.createScaledBitmap(background, finalBgWidth, finalBgHeight, true);
// 绘制时居中显示
canvas.drawBitmap(scaledBackground, (viewWidth - finalBgWidth)/2f, (viewHeight - finalBgHeight)/2f, null);

内容的提问来源于stack exchange,提问作者jai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 16:30:02