如何调整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
相关产品推荐
相关产品推荐

