1

以下を読んだ後:

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

Android 画像の ppi を dpi に変換するにはどうすればよいですか?

「dp=px/(dpi/160)」と仮定しました。LDPI 画面でテストしたところ、完全に機能しました。最初は「ついにブレークスルーだ!」と思いましたが、HDPI 画面でテストしたところ、うまく機能しないことがわかりました。それで、「dp = px * (dpi / 160)」を試してみたところ、うまくいかないことがわかりました。うまくいくとは思いませんでした...他のいくつかの式を試しましたが、どれもうまくいきませんでした。そのうちの 1 つは、小さな画面でのみ 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();

次に、次のコードを持つバッチャーに移動します...

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

ここで、私の 2 つの最大の質問は次のとおりです。1 つ目は、正しい数式を使用して、どこに描画し、何回背景を描画する必要があるかを計算していますか? 2 つ目は、要素を描画して dp をピクセルに戻すときの式が必要ですか?

失敗した場合は次のようになります。

Background_HDPI_SCREEN.png

黄色のマークは黒でよい場所、青の X マークは黒でよい場所ではありません。青は実際よりもはるかに長くなるはずです。

なぜこれが起こっているのか数学的に理解していますが、LDPI だけでなく、LDPI と HDPI の両方の画面で機能するより良い式があるように感じます。この式により、MDPI では少し小さくなります。

計算は、密度に依存しないピクセル (DP) = 幅 / (密度 / 160) です。たとえば、DP = 800/(240/160) = 800/1.5 = 533 となります。

それで、あなたの考えは何ですか?

ご意見をお寄せいただきありがとうございます。SSCCE が必要な場合はお知らせください。ただし、このインスタンスを作成するには時間がかかるため、これを行う必要がないことを願っています。

4

0 に答える 0