簡體   English   中英

Android-縮放我的UI以適合所有屏幕尺寸嗎?

[英]Android - Scaling my UI to fit all screen sizes?

到目前為止,我已經嘗試了多種將圖像縮放到屏幕尺寸的方法,但似乎沒有一種適合我。 我還是Java的新手,擁有適合任何屏幕尺寸的UI的想法對我來說似乎很陌生。 我正在使用Canvas類繪制位圖。 我嘗試創建一個scaledBitmap,但沒有發現任何區別。 我想要這樣一個簡單的主菜單屏幕

在此處輸入圖片說明

這肯定是一個非常普遍的問題,因為所有應用程序都需要這樣做。 我確實可以使用一些幫助來了解其工作原理。 在某些手機上看起來不錯,但在其他手機上,圖像太大或居中。

我的代碼如下。 如果有人可以在這里幫助我,這是針對一個即將到期的學校項目的: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); 

嘗試此操作,在圖像上使用scaleType =“ fitXY” ,它將跨到視圖的邊界。

您從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可以算出所有位圖資產的最終像素值。 xOffset它們時,必須相應地添加xOffsetyOffset才能正確偏移屏幕的空白區域,這是由於設備屏幕的縱橫比與游戲的預期縱橫比不同而造成的。 矩陣結合了所有這些內容,因此我們不必在每次繪制時都使用這些變量。 我們可以只使用矩陣。

繪制示例:

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

我只是寫了這篇文章而沒有真正測試它。 只是為了這個主意。 希望你能明白。

編輯2:已實現的xOffset和yOffset被顛倒了。 修復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM