如何获得正确的Android宽度和高度?

时间:2012-05-28 20:30:06

标签: android opengl-es screen

阅读以下内容后:

http://developer.android.com/guide/practices/screens_support.html

How do I convert ppi into dpi for Android images?

我认为“dp = px /(dpi / 160)”。我在LDPI屏幕上测试它并且它完美地工作,我的第一个想法是“终于,一个突破!”,但是在HDPI屏幕上测试之后我发现它没有那么好用。所以然后我尝试了“dp = px *(dpi / 160)”并发现它不起作用,而不是我认为它会......我尝试了其他一些公式,但它们都没有奏效。其中一个是仅在小屏幕上使用dp,然后只为其他屏幕获取屏幕px。那没用。

显然,在阅读了如何支持多个屏幕后,我想使用DP来获得正确的宽度和高度。我不太清楚为什么这会失败所以我为什么转向你。

这是我的代码:

public class Scale {

    ScreenType type;
    Display display;

    public Scale(WindowManager wm) {
        this.display = wm.getDefaultDisplay();

        // Get Display Type //
        DisplayMetrics metrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(metrics);
        int density = metrics.densityDpi;
        switch(density) {
            case DisplayMetrics.DENSITY_LOW:
                this.type = ScreenType.LDPI;
                break;
            case DisplayMetrics.DENSITY_MEDIUM:
                this.type = ScreenType.MDPI;
                break;
            case DisplayMetrics.DENSITY_HIGH:
                this.type = ScreenType.HDPI;
                break;
            default:
                this.type = ScreenType.XHDPI;
                System.exit(0);
                break;
        }
    }

    public ScreenType getScreenType() {
        return this.type;
    }

    public int getWidth() {
        return this.display.getWidth();
    }

    public int getHeight() {
        return this.display.getHeight();
    }

    public int getDPWidth() {
        float dp = this.getWidth() / (this.getScreenType().getDensity() / 160f);
        return (int) dp;
    }

    public int getDPHeight() {
        float dp = this.getHeight() / (this.getScreenType().getDensity() / 160f);
        return (int) dp;
    }

}

ScreenType枚举如下:

public enum ScreenType {
    LDPI(120), MDPI(160), HDPI(240), XHDPI(320);

    private final int density;
    ScreenType(int density) {
        this.density = density;
    }

    public int getDensity() {
        return this.density;
    }
}

我知道我不需要ScreenType枚举,但目前还没有谈论这个。只需要弄清楚为什么屏幕总是得到错误的大小。

现在,当我去绘制背景时,我会做以下事情......

batcher.beginBatch(Assets.loadingAtlas);
for(int x = 0; x <= this.scale.getDPWidth(); x += 50) {
    for(int y = 0; y <= this.scale.getDPHeight(); y += 50) {
        batcher.drawSprite(x, y, 50, 50, Assets.backgroundPattern);
    }
}
batcher.endBatch();

然后它进入具有以下代码的batcher ......

public void beginBatch(Texture texture) {
    texture.bind();
    numSprites = 0;
    bufferIndex = 0;
}

public void drawSprite(float x, float y, float width, float height, TextureRegion region) {
    float halfWidth = width / 2;
    float halfHeight = height / 2;
    float x1 = x - halfWidth;
    float y1 = y - halfHeight;
    float x2 = x + halfWidth;
    float y2 = y + halfHeight;

    verticesBuffer[bufferIndex++] = x1;
    verticesBuffer[bufferIndex++] = y1;
    verticesBuffer[bufferIndex++] = region.u1;
    verticesBuffer[bufferIndex++] = region.v2;

    verticesBuffer[bufferIndex++] = x2;
    verticesBuffer[bufferIndex++] = y1;
    verticesBuffer[bufferIndex++] = region.u2;
    verticesBuffer[bufferIndex++] = region.v2;

    verticesBuffer[bufferIndex++] = x2;
    verticesBuffer[bufferIndex++] = y2;
    verticesBuffer[bufferIndex++] = region.u2;
    verticesBuffer[bufferIndex++] = region.v1;

    verticesBuffer[bufferIndex++] = x1;
    verticesBuffer[bufferIndex++] = y2;
    verticesBuffer[bufferIndex++] = region.u1;
    verticesBuffer[bufferIndex++] = region.v1;

    numSprites++;
}

public void endBatch() {
    vertices.setVertices(verticesBuffer, 0, bufferIndex);
    vertices.bind();
    vertices.draw(GL10.GL_TRIANGLES, 0, numSprites * 6);
    vertices.unbind();
}

然后,当您绘制顶点时,使用以下代码...

public void draw(int primitiveType, int offset, int numVertices) {        
    GL10 gl = glGraphics.getGL();

    if(indices!=null) {
        indices.position(offset);
        gl.glDrawElements(primitiveType, numVertices, GL10.GL_UNSIGNED_SHORT, indices);
    } else {
        gl.glDrawArrays(primitiveType, offset, numVertices);
    }        
}

现在我最大的两个问题是:一,我是否使用正确的公式来计算我应该绘制的位置以及绘制背景的次数?二,当我绘制元素以将dp放回像素时,我应该有一个公式吗?

失败后会发生以下情况:

Background_HDPI_SCREEN.png

黄色标记可以黑色和蓝色X标记,黑色不合适。蓝色应该远远超过它。

我在数学上理解为什么会发生这种情况,但感觉可能有更好的公式可以用于LDPI和HDPI屏幕,而不仅仅是LDPI。这个公式也使它在MDPI上小一点。

数学是与密度无关的像素(DP)= WIDTH /(DENSITY / 160)。因此,一个例子是DP = 800 /(240/160)= 800 / 1.5 = 533

那你有什么想法?

提前感谢任何输入!如果你想要一个SSCCE让我知道,但这需要一些时间来制作这个实例,而我正在跳跃,我们不需要这样做。

0 个答案:

没有答案