1

私が知る限り (間違っている場合は訂正してください)、複数のサイズのデバイスで見栄えの良い (優れたアンチエイリアシング付きの) グラフィック ボタンを使用する場合は、異なるサイズの画像のセットを作成する必要があります。画像をさまざまなディレクトリのコレクション内に配置します。使用するディレクトリのセットと、それらのディレクトリに必要な相対サイズを正確に示す実際の例を探しています。

ところで、私が ImageButtons と言うとき、私はテキストの代わりに画像を含むことを意味します。

編集:私を特に混乱させることの1つは、人々が異なる画面密度を採用している例(chuck258の回答など)を非常によく目にするという事実です...しかし、幅と高さを密度に合わせて調整したボタンを作成すると、高密度でサイズの小さい画面を使用している場合、ボタンが非常に大きくなります。

編集:私の最後の編集に加えて、私が欲しいものについてもっと具体的にする必要があるかもしれません...約10%(8%から13%までの変動を受け入れます) (縦向きのみ) 画面の幅 ... どのサイズの画像を作成し、どのディレクトリに配置するか?

編集:画面の領域が広い場合は、アイコンが画面のより小さな部分を占めるようにするのが標準的な方法であるというメッセージが表示されます。おそらくこれは、アイコンが非常に大きくなることを許可すると、アイコンがおもちゃのように見えたり、子供っぽくなったりするためです。でも実は、子供向けのゲームアプリを作っているんです!だから、これはまさに私が欲しいものです。

4

8 に答える 8

11

まず、画面密度と画面サイズの違いを理解する必要があります。

画面サイズは、画面の対角線として測定された物理的なサイズです。Android では、すべての実際の画面サイズを、小、標準、大、特大の 4 つの一般化されたサイズにグループ化します。携帯電話の画面サイズは 4.9 インチで、通常と見なされます。Nexus 7 (2012 年の古いものと 2013 年の新しいもの) の画面サイズはどちらも 7 インチで、Nexus 10 は画面サイズが大きくなっています。 10 インチの特大サイズです。

一方、画面密度は、画面の物理領域内のピクセルの量です。通常、dpi (ドット/インチ) と呼ばれます。たとえば、「低」密度の画面は、「通常」または「高」密度の画面と比較して、特定の物理領域内のピクセルが少なくなります。簡単にするために、Android はすべての実際の画面密度を、低、中、高、および超高 (および新しい xxhdpi) の 4 つの一般化された密度にグループ化します。古い Nexus 7 の画面サイズは新しい Nexus 7 と同じですが、古い Nexus 7 の解像度は 1280x800、つまり 216 dpi または hdpi ですが、新しいものは 1920×1200 ピクセル、つまり 323 dpi または xhdpi (より多くのピクセル) です。同じ物理領域内にあるということは、dpi でのピクセル密度が高いことを意味します)。

画面密度が同じ場合、drawable フォルダー内の画像は、小さい画面、通常の画面、大きい画面、特大画面で同じ物理サイズになります。画面のサイズが異なるため、画像が占める割合も異なります。小さな画面では、大きな画面よりも大きな割合を占めます。

同じ画像が画面サイズ フォルダー (drawable-small、drawable-normal、drawable-large、drawable-xlarge) のいずれかにある場合は何も変わりませんが、画像のより大きなバージョンを drawable-xlarge に入れることを決定できます。その場合、画像は新しい Nexus 7 よりも Nexus 10 の方が大きくなります (どちらも xhdpi ピクセル密度です)。

画面のピクセル密度が異なる場合、同じ画像でも見た目が異なります。画像は、mdpi 画面と比較して xhdpi 画面の半分のサイズになります (xhdpi 画面のピクセル密度は約 2 倍であるため):
http://developer.android.com/images/screens_support/density-test-bad.png

アイコンの場合、通常、異なる画面で同じサイズにする必要があります。そのため、たとえば、mdpi 画面のメニュー アイコンは 32x32 で、xhdpi 画面のメニュー アイコンは 64x64 であり、どちらも適切な描画可能フォルダー (drawable-mdpi および drawable-xhdpi) にあります:
http://developer.android.com/images/screens_support/density -test-good.png

では、いつピクセル密度を使用し、いつ画面サイズのドローアブル フォルダーを使用しますか?

ピクセル密度フォルダーは、通常、必要なさまざまな画面密度の画面で画像の物理サイズを同じにする必要がある場合に使用されます。古い Nexus 7 と新しい Nexus 7 に同じ画像を使用すると、画面の物理的なサイズが同じであってもサイズが異なり、それは望ましくありません。そのため、密度依存の画像を使用することが不可欠です。

小さい、通常、大きい、特大の画面で画像の物理サイズを変更する場合は、画面サイズ フォルダーを使用します。メイン画面に 6 つのアイコンを含むグリッド ナビゲーションがあり、大きな画面で余分な画面領域を利用したくない場合 (アイコンを追加するなど)、小さな画面に小さな画像を提供します。大画面の大きな画像。前に説明したように、画面サイズに依存する画像の上に密度に依存する画像を提供する必要があります (古い Nexus 7 と新しい Nexus 7 の例)。

したがって、理論的には、同じ画像に対して 16 の異なるリソースが必要になります (4 つの画面密度で 4 つの画面サイズ、または新しい xxhdpi 密度では 5 つの密度でも -> 20 リソース)。もちろん、多くの画像がある場合は特に、それほど多くのリソースを作成したいと思う人はいません。1 つのアプローチは、誰かが提案したようにダッシュボードを使用すること です
。 hdpi および normal/xhdpi (全デバイスの 81%)。そうすれば、リソースをわずか 4 に減らすことができます。
もう 1 つの方法は、画面サイズまたは画面密度のいずれかのリソースを提供し (ここでも 4 つのリソースのみが必要です)、コードでスケーリングを行うことです。

画面密度に依存するリソースがある場合は、たとえば、このhttps://stackoverflow.com/a/5016350/534471を使用して画像を縮小します (決して拡大しないでください)。

画面サイズに依存するリソースがある場合は、このhttp://developer.android.com/reference/android/util/DisplayMetrics.htmlを使用 して画像を縮小します。

ここにすべての良い例があります (ソースコードを含む): https://www.captechconsulting.com/blog/steven-byle/understanding-density-independence-android

特定の問題については、フォルダー drawable で 1 つの汎用イメージを使用できます。その画像のサイズは、拡大する必要がないようにする必要があります(見栄えが悪いため)。次のようにレイアウトでボタンを定義します。

<ImageButton
    android:id="@+id/myButton"
    android:src="@drawable/myDrawable"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    android:adjustViewBounds="true"
/>

このコードと一緒に、ボタンは画面の 10% にスケーリングされます。

Display display = getWindowManager().getDefaultDisplay();
Point screenSize = new Point();
display.getRealSize(screenSize);
int size = Math.min(screenSize.x, screenSize.y);
int buttonSize = Math.round(size * 0.1f);
ImageButton button = (ImageButton) findViewById(R.id.myButton);
button.setMaxWidth(buttonSize);
button.setMaxHeight(buttonSize);

元の画像の大きさはどのくらいですか?
Nexus 10 は、現時点でおそらくすべての Android デバイスの中で最高の画面解像度を備えています。1600 ピクセルは、xhdpi ディスプレイで 3200 密度非依存ピクセルに変換されます。3200 の 10% は 320 です。320x320 の画像を使用すると、既存のすべてのデバイスで良好な結果が得られます。
ただし、このアプローチには落とし穴があります。
320x320 はかなり大きい (おそらく 24/32 ビットの色深度) ため、メモリの問題が発生する可能性があります。密度に依存するドローアブル フォルダーに同じリソースを提供すると、hdpi、mdpi、および ldpi デバイスのメモリ フットプリントを下げることができます。

  • ドローアブル-xhdpi: 320x320
  • ドローアブル hdpi: 240x240
  • ドローアブル-mdpi: 160x160
  • ドローアブル ldpi: 120x120

画面サイズのドローアブル フォルダーを使用すると、これをさらに改善できます (画面が小さいほど小さい画像が必要になります) が、前述のように 16 または 20 個のリソースを提供する必要があります。最終的には、一方のメモリ フットプリント/速度と、他方の保守性/リソースの作成時間/apk サイズの間のトレードオフになります。

于 2013-10-19T03:33:44.190 に答える
1

Android プラットフォームの通常の方法は、画面サイズではなく、さまざまな画面密度の画像のみを提供することです。タブレットなら大きな画像は見たくない、もっと情報が欲しい。したがって、ビューのサイズを大きくするのではなく、より大きな画面には別のレイアウトを提供することをお勧めします。

ただし、画面幅の 10% の画像を提供する特定の理由がある場合は、異なる修飾子で「描画可能」フォルダーを使用できます。「使用可能な幅」、「画面サイズ」、および「画面のピクセル密度」修飾子に関心があります。たとえば、次の画像を提供します。

  • drawable-sw320dp-mdpi - 画像幅 32px
  • drawable-sw320dp-hdpi - 画像幅 48px
  • drawable-sw320dp-xhdpi - 画像幅 64px
  • drawable-sw400dp-mdpi - 画像幅 40px
  • ... サポートが必要なすべてのデバイスのイメージを提供します
于 2013-10-18T11:10:40.680 に答える
0

次のようなことができます。

package com.example.test;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.Menu;
import android.widget.ImageButton;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Get ImageButton from XML
        ImageButton ib = (ImageButton) findViewById(R.id.imageButton);
        //Get the screen size
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        //10% of the screen width
        int width = (int) (size.x * 0.1);
        //Get and scale the Bitmap (10% of screen width)
        Bitmap bitmap = getImage(R.drawable.ic_launcher, width, width);
        ib.setImageBitmap(bitmap);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }


    public Bitmap getImage (int id, int width, int height) {
        Bitmap bmp = BitmapFactory.decodeResource( getResources(), id );
        Bitmap img = Bitmap.createScaledBitmap( bmp, width, height, true );
        bmp.recycle();
        return img;
    }
}

そしてImageButton:

<ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageButton" />
于 2013-10-24T07:43:40.970 に答える