Android - 扩展我的UI以适应所有屏幕尺寸?

时间:2014-06-12 17:51:13

标签: java android canvas bitmap scaling

到目前为止,我已经尝试了很多将图像缩放到屏幕尺寸的方法,但它们似乎都不适用于我。我仍然是java的新手,并且拥有适合任何屏幕尺寸的UI的想法对我来说似乎很陌生。我正在使用Canvas类绘制位图。我尝试过创建一个scaledBitmap并且没有看到任何区别。我想要一个像这样的简单主菜单屏幕

enter image description here

这一定是一个非常常见的问题,因为所有应用都需要这样做。我真的可以使用一些帮助来理解它是如何工作的。在某些手机上看起来不错,但在其他手机上,图像太大或偏离中心。

我的代码如下。如果有人可以帮我在这里,这是一个学期项目即将到期:P谢谢你们!

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

    titleBounds = new RectF();
    playBounds = new RectF();
    scoreBounds = new RectF();
    soundBounds = new RectF();
    creditBounds = new RectF();

    titlePaint = new Paint();
    playPaint = new Paint();

    play = BitmapFactory.decodeResource(getResources(), R.drawable.play);
    playGlow = BitmapFactory.decodeResource(getResources(), R.drawable.playglow);


    sound = BitmapFactory.decodeResource(getResources(), R.drawable.sound);
    soundGlow = BitmapFactory.decodeResource(getResources(), R.drawable.soundglow);


    // Get window size and save it to screenWidth and screenHeight.
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size); 
    screenWidth = size.x;
    screenHeight = size.y;

    playy = Bitmap.createScaledBitmap(play, convertToPx(screenWidth), convertToPx(screenHeight), true);


    playSound(context, R.raw.loop);


}

public int convertToPx(int dp) {
    // Get the screen's density scale
    final float scale = getResources().getDisplayMetrics().density;
    // Convert the dps to pixels, based on density scale
    return (int) (dp * scale + 0.5f);
}


@Override protected void onDraw(Canvas canvas) {


    ViewGroup parent = (ViewGroup)getParent();

    playBounds.set(screenWidth / 2 - play.getWidth() / 2, screenHeight * 1/3 - play.getHeight() / 2, playBounds.left + play.getWidth(), playBounds.top + play.getHeight());
    soundBounds.set(playBounds.centerX() - sound.getWidth() / 2, playBounds.bottom + 10, soundBounds.left + sound.getWidth(), soundBounds.top + sound.getHeight());


    if (playClick == false) canvas.drawBitmap(playy, null, playBounds, null);
    else canvas.drawBitmap(playGlow, null, playBounds, null);   

    if (soundClick == false) canvas.drawBitmap(sound, null, soundBounds, null);
    else canvas.drawBitmap(soundGlow, null, soundBounds, null); 

2 个答案:

答案 0 :(得分:0)

试试这个,在图片上使用 scaleType =" fitXY" ,这将覆盖到视图的边界。

答案 1 :(得分:0)

您从wm.getDefaultDisplay()获得的屏幕尺寸.getSize()以像素为单位,而不是以dp为单位。所以你可以在不转换的情况下使用它们。

像...一样的东西。

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size); 
screenWidth = size.x;
screenHeight = size.y;
playy = Bitmap.createScaledBitmap(play, screenWidth, screenHeight, true);

如果您正在尝试创建游戏,我建议您不要使用Canvas。相反,您应该使用更快的GLSurfaceView。更好的是,使用像Corona SDK或Unity或Cocos2dx这样的跨平台游戏引擎。通过这种方式开发将变得更加容易,而且性能也会很好。

编辑:您最终想要的是在不改变宽高比的情况下对所有资产进行一致缩放。你需要编写一个辅助方法来计算出这个比例,然后将这个比率乘以你的所有维数。

// The code below assume some variables are already populated by the above code
// I HAVE NOT TESTED THIS CODE. I'M JUST WRITING IT HERE OFF THE TOP OF MY HEAD.

private static float dimRatio;
private static float xOffset;
private static float yOffset;
private static Matrix transformMatrix;

private void initializeBitmapTransformMatrix {
    float ratio = (float)screenWidth / (float)gameWidth; //gameWidth is the width of your background image asset - so it's base size of the game
    if(gameHeight * ratio > screenHeight ){
        // the ratio we calculated above is for the width based scaling.
        // seems like if we use this ratio, the height will go off the boundary.
        // so use the height based ratio instead
        dimRatio = (float)screenHeight / (float)gameHeight;   
        xOffset = (screenWidth - (gameWidth * dimRatio)) / 2;
    } else {
        dimRatio = ratio;
        yOffset = (screenHeight - (gameHeight * dimRatio)) / 2;
    }

    // Now you have the ratio and offset values make a transform matrix

    transformMatrix = new Matrix();
    transformMatrix.setScale(dimRatio, dimRatio);
    transformMatrix.setTranslate(xOffset, yOffset);
}

说明:我们dimRatio计算出所有位图资源的最终像素值。当您定位它们时,您必须相应地添加xOffsetyOffset以正确偏移屏幕的空白区域,这是因为设备屏幕的宽高比与您的游戏不同#39;预期的宽高比。矩阵结合了所有这些,所以我们每次绘制时都不必使用这些变量。我们可以使用矩阵。

绘制示例:

canvas.drawBitmap(play, transformMatrix, null); // for background
// for a button
Matrix buttonMatrix = new Matrix(transformMatrix);
buttonMatrix.postTranslate(20f*dimRatio, 100f*dimRatio);
canvas.drawBitmap(button, buttonMatrix, null);

我刚写完这篇文章而没有真正测试过。这只是为了这个想法。希望你明白这一点。

EDIT2:已实现的xOffset和yOffset被反转。修正了它。

相关问题