以下を読んだ後:
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 をピクセルに戻すときの式が必要ですか?
失敗した場合は次のようになります。
黄色のマークは黒でよい場所、青の X マークは黒でよい場所ではありません。青は実際よりもはるかに長くなるはずです。
なぜこれが起こっているのか数学的に理解していますが、LDPI だけでなく、LDPI と HDPI の両方の画面で機能するより良い式があるように感じます。この式により、MDPI では少し小さくなります。
計算は、密度に依存しないピクセル (DP) = 幅 / (密度 / 160) です。たとえば、DP = 800/(240/160) = 800/1.5 = 533 となります。
それで、あなたの考えは何ですか?
ご意見をお寄せいただきありがとうございます。SSCCE が必要な場合はお知らせください。ただし、このインスタンスを作成するには時間がかかるため、これを行う必要がないことを願っています。