複数画面をサポートする

Android は、サイズと密度が異なる画面を備えたさまざまな端末上で動作します。アプリの場合、Android システムにより、端末間で一貫した開発環境が提供され、各アプリのユーザー インターフェースを表示画面に適合させるための大部分の処理が実行されます。 また、さまざまな画面設定の UI 設計を最適化するために、特定の画面サイズや密度向けにアプリの UI を制御できるようにする API が提供されます。 たとえば、ハンドセット用の UI とは異なるタブレット用の UI が必要になる場合があります。

システムによりスケーリングとサイズ変更が実行され、さまざまな画面上でアプリが動作するようになりますが、サイズと密度が異なる画面用にアプリを最適化する必要があります。 これにより、すべての端末のユーザー エクスペリエンスが最適化され、ユーザーは、端末の画面に合わせてアプリが単に伸縮されたのではなく、ユーザーの端末用に実際にアプリが設計されていると感じます。

このドキュメントで説明しているベスト プラクティスを順守することにより、単一の .apk ファイルを使用して、サポートされているすべての画面設定で適切に表示されるアプリを作成し、最適なユーザー エクスペリエンスを実現することができます。

注: このドキュメントの情報は、Android 1.6(API レベル 4)以降向けに設計されたアプリを対象にしています。 アプリが Android 1.5 以前をサポートしている場合は、最初に Android 1.5 の戦略を読んでください。

また、Android 3.2 では、新しい API が導入されており、さまざまな画面サイズに対応するために、アプリで使用するレイアウト リソースをより細かく制御できるようになっていることに注意してください。 タブレット用に最適化されたアプリを開発している場合は、これらの新しい機能が特に重要になります。詳細については、Android 3.2 のタブレット レイアウトの宣言のセクションを参照してください。

画面のサポートの概要

このセクションでは、このドキュメントおよび API で使用される用語とコンセプトの紹介、システムがサポートする画面設定の概要、API と基盤となる画面の互換性機能の概要など、複数の画面に対する Android のサポートについて説明しています。

用語とコンセプト

画面サイズ
画面の対角線で計測した実際の物理サイズ。

簡潔にするため、Android では、実際のすべての画面サイズを small(小)、normal(通常)、large(大)、extra-large(特大)の 4 つの汎用サイズに分類しています。

画面密度
画面の物理領域内にあるピクセル数。通常、dpi(1 インチあたりのドット数)と呼ばれます。 たとえば、「medium(中)」または「high(高」」密度画面と比較すると、「low(低)」密度画面の特定の物理領域内にあるピクセル数はより少なくなります。

簡潔にするため、Android では、実際のすべての画面密度を low(低)、medium(中)、high(高)、extra-high(超高)、extra-extra-high(超超高)、extra-extra-extra-high(超超超高)の 6 つの汎用密度に分類しています。

画面の向き
ユーザーの視点で見た画面の向き。画面の向きは、横向きまたは縦向きのいずれかです。つまり、画面のアスペクト比は横長または縦長のいずれかになります。 異なる端末はデフォルトで異なる画面の向きで動作するだけでなく、ユーザーが端末を回転させると、実行時に画面の向きが変わることに注意してください。
解像度
画面上の物理ピクセルの総数。複数の画面のサポートを追加すると、アプリでは、解像度が直接操作されなくなります。アプリでは、汎用サイズと汎用密度の分類で指定されている画面サイズと画面密度のみを考慮する必要があります。
密度非依存ピクセル(dp)
UI レイアウトを定義するときに使用する必要のある仮想ピクセル単位。レイアウトの寸法または位置を密度に依存しない方法で表すために使用します。

密度非依存ピクセルは 160 dpi 画面の 1 つの物理ピクセルと同等です。これは、「medium(中)」密度画面用に想定される基準密度です。 使用している画面の実際の密度に基づいて、必要に応じて、dp 単位のスケーリングが透過的に処理されます。 dp 単位から画面ピクセルへの変換は簡単です px = dp * (dpi / 160))。たとえば、240 dpi の画面では、1 dp が 1.5 物理ピクセルに相当します。 アプリの UI を定義するときは、常に dp 単位を使用して、密度が異なる画面に UI が適切に表示されるようにする必要があります。

サポートされる画面の範囲

Android 1.6(API レベル 4)以降では、複数の画面サイズと画面密度がサポートされており、端末が備えている可能性のある多くの異なる画面設定が反映されています。 Android システムの機能を使用して、アプリのユーザー インターフェースを各画面設定用に最適化することにより、アプリで適切にレンダリングを実行し、各画面で可能な限り最適なユーザー エクスペリエンスを実現できます。

複数の画面に対応したユーザー インターフェースをシンプルに設計できるようにするため、Android では実際の画面サイズと密度の範囲を以下のように分類しています。

  • small(小)、normal(通常)、large(大)、xlarge(特大)の 4 つの汎用サイズのセット:

    注: Android 3.2(API レベル 13)以降では、利用可能な画面の幅に基づいて画面サイズを管理する新しい技術が活用されるため、これらの画面サイズの分類は廃止されています。 Android 3.2以降向けのアプリを開発している場合は、Android 3.2 のタブレット レイアウトの宣言で詳細をご確認ください。

  • 6 つの汎用密度のセット:
    • ldpi(low(低))~120dpi
    • mdpi(medium(中))~160dpi
    • hdpi(high(高))~240dpi
    • xhdpi(extra-high(超高))~320dpi
    • xxhdpi(extra-extra-high(超超高))~480dpi
    • xxxhdpi(extra-extra-extra-high(超超超高))~640dpi

汎用サイズと汎用密度は、基準設定(つまり、normal(通常)サイズおよび mdpi(medium(中))密度)を中心に展開されます。 この基準設定は、HVGA 画面(Android 1.6 までは、HVGA 画面が Android でサポートされる唯一の画面設定でした)を備えた、最初の Android 対応端末である T-Mobile G1 の画面設定に基づいています。

それぞれの汎用サイズと汎用密度は、実際の画面サイズと画面密度の範囲をカバーしています。たとえば、normal(通常)サイズの画面を備えているとされる 2 つの端末を手にしたとき、それらの実際の画面サイズとアスペクト比がわずかに異なっている場合があります。 同様に、hdpi の画面密度を備えているとされる 2 つの端末の実際のピクセル密度がわずかに異なっている場合もあります。Android では、アプリに対してこれらの違いを抽象化することにより、汎用サイズと汎用密度用に設計された UI を提供できるようにし、必要に応じて、システムで最終的な調整を行います。 図 1 は、さまざまなサイズと密度がさまざまなサイズと密度のグループにおおまかに分類される方法を示しています。

図 1 Android で実際のサイズと密度がどのように汎用サイズと汎用密度に分類されるかを示した図。

デベロッパーはさまざまな画面サイズ用の UI を設計する際に、各設計で最小限のスペースが要求されることに気付くでしょう。 したがって、上記の各汎用画面サイズには、システムで定義された最小解像度が関連付けられています。 これらの最小サイズは「dp」単位(レイアウトを定義するときに使用する必要のある単位と同じ単位)であり、dp 単位を使用することにより、システムでは画面密度の変更について考慮する必要がなくなります。

  • xlarge(特大)画面の最小サイズは 960dp x 720dp
  • large(大)画面の最小サイズは 640dp x 480dp
  • normal(通常)画面の最小サイズは 470dp x 320dp
  • small(小)画面の最小サイズは 426dp x 320dp

注: Android 3.0 より前のバージョンでは、最小画面サイズの定義が明確ではなかったため、一部の端末では、normal(通常)サイズと large(大)サイズ間の分類が間違っている場合があります。また、これらのサイズは、画面の物理的解像度に基づいているため、端末によって異なる場合があります。たとえば、システムバーを備えた 1024x720 のタブレットは、スペースがシステムバーによって使用されるため、アプリが実際に利用できるスペースが少し小さくなります。

さまざまな画面サイズと画面密度用にアプリの UI を最適化するために、汎用サイズと汎用密度の代替リソースを提供することができます。 通常、一部の異なる画面サイズ向けには代替レイアウトを、異なる画面密度向けには代替ビットマップ画像を用意する必要があります。 システムは実行時に、現在の端末画面の汎用サイズまたは汎用密度に基づいて、アプリの適切なリソースを使用します。

画面サイズと画面密度のすべての組み合わせに対して代替リソースを用意する必要はありません。 以下のベスト プラクティスで説明しているように、UI を適切にサイズ変更するための手法を活用して UI を実装している場合、システムによって、あらゆる端末画面でアプリをレンダリングする処理の大部分を実行できる堅牢な互換性機能が提供されます。

注: 端末の汎用画面サイズと汎用画面密度を定義する特性は相互に独立しています。 たとえば、WVGA 高密度画面は、その物理サイズが T-Mobile G1(Android の最初の端末であり、基準の画面設定となる)の画面サイズとほぼ同じであるため、normal(通常)サイズの画面であると見なされます。 一方、WVGA 中密度画面は、large(大)サイズの画面であると見なされます。 WVGA 中密度画面は同じ解像度(同じピクセル数)を提供しますが、画面密度がより低くなります。つまり、各ピクセルが物理的に大きいため、画面全体が基準の(normal(通常)サイズの)画面よりも大きくなります。

密度非依存

アプリが異なる密度で画面に表示されるときに、ユーザー インターフェース要素の物理サイズ(ユーザーから見た)が維持されている場合に、アプリで「密度非依存」が実現します。

密度非依存でない場合、低密度画面では UI 要素(ボタンなど)が物理的に大きく表示され、高密度画面では物理的に小さく表示されるため、密度非依存を維持することが重要になります。 このような密度関連のサイズ変更により、アプリのレイアウトとユーザビリティに支障が出ることがあります。 図 2 と図 3 は、密度非依存ではない場合のアプリと密度非依存の場合のアプリの違いを示しています。

図 2 異なる密度のサポートが提供されない場合に低密度画面、中密度画面、および高密度画面に表示されたアプリの例。

図 3 異なる密度のサポートが提供される場合に低密度画面、中密度画面、および高密度画面に表示されたアプリ(密度に依存しない)の例。

Android システムでは、次の 2 つの方法によりアプリで密度非依存を実現します。

  • 必要に応じて、現在の画面密度向けに dp 単位をスケーリングする
  • 必要に応じて、現在の画面密度に基づいて、ドローアブル リソースを適切なサイズにスケーリングする

図 2 では、テキストビューとビットマップ ドローアブルの寸法がピクセル(px 単位)で指定されているため、低密度画面では物理的に大きく表示され、高密度画面では物理的に小さく表示されています。 これは、実際の画面サイズが同じであっても、高密度画面では 1 インチあたりのピクセル数がより多いためです(同じ数のピクセルがより小さな領域に収まる)。 図 3 では、レイアウトの寸法が密度非依存ピクセル(dp 単位)で指定されています。 密度非依存ピクセルの基準は中密度画面であるため、中密度画面の端末に表示されたアプリは、図 2 の中密度画面の端末に表示されたアプリと同じに見えます。しかし、低密度画面と高密度画面では、必要に応じて、画面に適合させるために密度非依存ピクセルの値がそれぞれスケールダウンおよびスケールアップされます。

ほとんどの場合、必要に応じて、すべてのレイアウト寸法の値を密度非依存ピクセル(dp 単位)または "wrap_content" で指定するだけで、アプリで密度非依存を実現することができます。 すると、現在の画面密度の適切なスケーリング係数に基いて、ビットマップ ドローアブルを適切なサイズで表示するために、必要に応じてビットマップ ドローアブルがスケーリングされます。

ただし、上記のスクリーンショットで示されているように、ビットマップ スケーリングにより、ビットマップがぼやけたり、粗い表示になったりする場合があります。 これらの現象を回避するには、異なる画面サイズに対して代替ビットマップ リソースを提供する必要があります。 たとえば、高密度画面に対しては高解像度のビットマップを提供する必要があります。そうすると、システムでは、中密度画面向けに設計されたビットマップのサイズを変更する代わりに、これらの高解像度のビットマップを使用します。 次のセクションでは、さまざまな画面設定に代替リソースを提供する方法について詳しく説明します。

複数の画面をサポートする方法

Android が複数の画面をサポートする際に基盤となるのは、現在の画面設定でアプリのレイアウトとビットマップ ドローアブルのレンダリングを適切に管理する機能です。 システムでは、各画面設定でアプリを適切にレンダリングするためのタスクの大部分が処理され、必要に応じて、画面サイズおよび画面密度に合わせるためにレイアウトをスケーリングしたり、画面密度に対応させるためにビットマップ ドローアブルをスケーリングしたりします。 ただし、異なる画面設定をより適切に処理するには、以下を行う必要があります。

  • アプリがサポートする画面サイズをマニフェストで明示的に宣言する

    アプリがサポートする画面サイズを明示的に宣言することにより、サポートされる画面サイズを備えた端末のみがアプリをダウンロードできるようにすることができます。 また、異なる画面サイズのサポートを宣言すると、アプリが画面互換性モードで実行されているかどうかに関係なく、特により大きな画面でのアプリの描画方法に影響が出る可能性があります。

    アプリがサポートする画面サイズを宣言するには、マニフェスト ファイルに <supports-screens> 要素を含める必要があります。

  • 異なる画面サイズに対して異なるレイアウトを提供する

    Android はデフォルトでアプリのレイアウトのサイズを変更して、現在の端末画面に適合させます。ほとんどの場合、この処理は適切に機能します。 一部のケースでは、異なる画面サイズで UI が適切に表示されない可能性があり、調整が必要になることがあります。 たとえば、より大きな画面では、追加の画面スペースを活用するために一部の要素の位置とサイズを調整し、より小さな画面では、すべての要素が画面に収まるようにそれらのサイズの調整が必要になる場合があります。

    サイズ固有のリソースを提供するために使用できる設定修飾子は、smallnormallarge、および xlarge です。 たとえば、extra-large(特大)画面用のレイアウトは、layout-xlarge/ に配置する必要があります。

    Android 3.2(API レベル 13)以降では、上記のサイズ グループのサポートが終了しているため、sw<N>dp 設定修飾子を使用して、レイアウト リソースに必要な利用可能な最小幅を定義する必要があります。 たとえば、タブレット用のマルチペイン レイアウトに少なくとも 600dp の画面幅が必要な場合、そのレイアウトを layout-sw600dp/ に配置する必要があります。 新しい手法を活用したレイアウト リソースの宣言に関する詳細については、Android 3.2 のタブレット レイアウトの宣言のセクションを参照してください。

  • 異なる画面密度に対して異なるビットマップ ドローアブルを提供する

    Android では、デフォルトでビットマップ ドローアブル(.png.jpg、および .gif ファイル)と 9-patch ドローアブル(.9.png ファイル)がスケーリングされ、各端末でこれらのドローアブルが適切な物理サイズでレンダリングされます。 たとえば、アプリで基準の中密度画面(mdpi)のみ対してビットマップ ドローアブルが提供される場合、高密度画面では、システムによりこれらのドローアブルがスケールアップされ、低密度画面では、ドローアブルがスケールダウンされます。 このスケーリングにより、ビットマップが乱れる可能性があります。 ビットマップを最適な状態で表示するには、異なる画面密度に対しては、異なる解像度の代替バージョンを含める必要があります。

    密度固有のリソース用に使用できる設定修飾子(以下に詳細を説明している)は、ldpi(low(低))、mdpi(medium(中))、hdpi(high(高))、xhdpi(extra-high(超高))、xxhdpi(extra-extra-high(超超高))、および xxxhdpi(extra-extra-extra-high(超超超高))です。 たとえば、高密度画面用のビットマップは drawable-hdpi/ に配置する必要があります。

    注: mipmap-xxxhdpi 修飾子が必要になるのは、xxhdpi 端末で通常よりも大きく表示されるランチャー アイコンを提供する場合のみです。 アプリのすべての画像に対して xxxhdpi アセットを提供する必要はありません。

    一部の端末はランチャー アイコンを 25% 程度スケールアップします。たとえば、最も密度の高いランチャー アイコン画像が既に超超高密度である場合、スケーリング プロセスにより、この画像の鮮明さが損なわれます。 したがって、より密度の高いランチャー アイコンを mipmap-xxxhdpi ディレクトリに配置する必要があります。そうすると、システムでは、より小さなバージョンのアイコンをスケールアップする代わりに、この密度の高いランチャー アイコンを使用します。

    詳細については、xxx 高密度ランチャー アイコンの提供を参照してください。 ランチャー アイコン以外の UI 要素に対して xxxhdpi 修飾子を使用しないでください。

注: すべてのランチャー アイコンを、res/drawable-[density]/ フォルダではなく、res/mipmap-[density]/ フォルダに配置してください。 Android システムでは、アプリがインストールされている端末の画面解像度に関係なく、mipmap-xxxhdpi など、これらの密度固有のフォルダにリソースが保持されます。 そのため、ランチャー アプリによって最適な解像度のアイコンが選択され、そのアイコンがホーム画面に表示されるようになります。 Mipmap フォルダの使用方法については、プロジェクトの概要の管理をご覧ください。

サイズと密度の設定修飾子は、上記のサポートされる画面の範囲で説明した汎用サイズと汎用密度に対応しています。

注: 設定修飾子や、システムが設定修飾子を使用して代替リソースを適用する方法について熟知していない場合は、代替リソースを提供するで詳細をご確認ください。

システムでは実行時に、任意のリソースに対して次の手順を使用し、その時点で可能な限り最適な画面を表示します。

  1. 適切な代替リソースを使用する

    現在の画面サイズと画面密度に基づいて、アプリに提供されているサイズ固有および密度固有のリソースが使用されます。 たとえば、端末が高密度画面を備えているときに、アプリがドローアブル リソースをリクエストした場合、端末の設定に最適なドローアブル リソース ディレクトリが検索されます。 利用可能なその他の代替リソースにもよりますが、hdpi 修飾子(drawable-hdpi/ など)が付いたリソース ディレクトリが最適なディレクトリになるため、システムではこのディレクトリのドローアブル リソースを使用します。

  2. 適合するリソースが利用できない場合、デフォルトのリソースが使用され、現在の画面サイズと画面密度に適合させるために、必要に応じて、そのリソースがスケールアップまたはスケールダウンされる

    「デフォルト」のリソースとは、設定修飾子がタグ付けされていないリソースです。たとえば、drawable/ のリソースは、デフォルトのドローアブル リソースです。 システムでは、デフォルトのリソースは、基準の画面サイズと画面密度(normal(通常)の画面サイズと medium(中)の画面密度)用に設計されていることを前提としています。 そのため、必要に応じて、高密度画面向けにデフォルトのリソースがスケールアップされ、低密度画面向けにデフォルトのリソースがスケールダウンされます。

    ただし、システムが密度固有のリソースを探したときに、密度固有のディレクトリでそのリソースが見つからない場合、デフォルトのリソースを常に使用するとは限りません。 スケーリングをより適切に実行するために、密度固有のその他のリソースが使用される場合があります。 たとえば、低密度用のリソースを探したときに、そのリースが利用できない場合は、そのリソースの高密度バージョンがスケールダウンされます。中密度用のリソースを係数 0.75 でスケールダウンするよりも、高密度用のリソースを係数 0.5 で低密度用のリソースにスケールダウンする方が簡単だからです。

Android で設定修飾子と端末設定を照合して、代替リソースを選択する方法の詳細については、Android が最適なリソースを見つける仕組みを参照してください。

設定修飾子の使用

Android では、現在の端末画面の特性に基づいて代替リソースが選択される方法を制御可能にする設定修飾子が複数サポートされています。 設定修飾子は Android プロジェクトのリソース ディレクトリに付加できる文字列であり、内部の設計済みリソースの設定を指定します。

設定修飾子を使用するには:

  1. プロジェクトの res/ ディレクトリに新しいディレクトリを作成し、<resources_name>-<qualifier> の形式を使用してこのディレクトリに名前を付けます。
    • <resources_name> は、標準のリソース名( drawablelayout など)です。
    • <qualifier> は、以下の表 1 にある設定修飾子であり、これらのリソースが使用される画面設定(hdpixlarge など)を指定します。

    一度に複数の <qualifier> を使用することができます。この場合、各修飾子はダッシュで区切ります。

  2. 設定固有の適切なリソースをこの新しいディレクトリに保存します。リソース ファイルの名前は、デフォルトのリソース ファイルと同じものにする必要があります。

たとえば、xlarge は、extra-large(特大)画面用の設定修飾子です。この文字列をリソース ディレクトリ名に付加すると(layout-xlarge など)、extra-large(特大)画面を備えた端末でこれらのリソースが使用されることがシステムに通知されます。

表 1 さまざまな画面設定に対して特別なリソースを提供できるようにする設定修飾子。

画面の特性 修飾子 説明
サイズsmall小サイズの画面用のリソース。
normal通常サイズの画面用のリソース (このサイズが基準のサイズになる)。
large大サイズの画面用のリソース。
xlarge特大サイズの画面用のリソース。
密度ldpi低密度(ldpi)の画面(~120dpi)用のリソース。
mdpi中密度(mdpi)の画面(~160dpi)用のリソース (この密度が基準の密度になる)。
hdpi高密度(hdpi)の画面(~240dpi)用のリソース。
xhdpi超高密度(xhdpi)の画面(~320dpi)用のリソース。
xxhdpi超超高密度(xxhdpi)の画面(~480dpi)用のリソース。
xxxhdpi超超超高密度(xxxhdpi)の画面(~640dpi)用のリソース。 この修飾子は、ランチャー アイコンのみに対して使用します。上記のを参照してください。
nodpiすべての密度の画面用のリソース。 これらは、密度非依存のリソースです。システムは、現在の画面密度に関係なく、この修飾子がタグ付けされたリソースをスケーリングしません。
tvdpi密度が mdpi と hdpi の間の画面(約 213dpi)用のリソース。 これは「プライマリ」の密度グループとしては認識されません。 ほとんどの場合、これはテレビ向けのものであり、大部分のアプリは必要としません。通常、アプリの場合は、mdpi と hdpi のリソースを提供すれば十分であり、システムが必要に応じてサイズを変更します。 tvdpi のリソースを提供する必要がある場合は、そのリソースを係数 1.33*mdpi でサイズ変更する必要があります。 たとえば、密度が mdpi の画面用の 100px x 100px 画像は、tvdpi 用にすると 133px x 133px になります。
画面の向きland横向きの画面(横長のアスペクト比)用のリソース。
port縦向きの画面(縦長のアスペクト比)用のリソース。
アスペクト比long基準の画面設定よりも大幅に縦長または横長のアスペクト比(縦向きまたは横向きにしたとき)を持つ画面用のリソース。
notlong基準の画面設定と類似したアスペクト比を持つ画面用のリソース。

注: Android 3.2 以降向けのアプリを開発している場合は、特定の画面サイズ用のレイアウト リソース宣言に必要な新しい設定修飾子(表 1 のサイズ修飾子ではなく)の詳細について、Android 3.2 のタブレット レイアウトの宣言のセクションを参照してください。

これらの修飾子が実際の画面サイズと画面密度にどのように対応しているかに関する詳細については、前述のサポートされる画面の範囲を参照してください。

たとえば、次のアプリケーション リソース ディレクトリは、さまざまな画面サイズとドローアブル向けのさまざまなレイアウト デザインを提供します。 ランチャー アイコンには mipmap/ フォルダを使用してください。

res/layout/my_layout.xml              // layout for normal screen size ("default")
res/layout-large/my_layout.xml        // layout for large screen size
res/layout-xlarge/my_layout.xml       // layout for extra-large screen size
res/layout-xlarge-land/my_layout.xml  // layout for extra-large in landscape orientation

res/drawable-mdpi/graphic.png         // bitmap for medium-density
res/drawable-hdpi/graphic.png         // bitmap for high-density
res/drawable-xhdpi/graphic.png        // bitmap for extra-high-density
res/drawable-xxhdpi/graphic.png       // bitmap for extra-extra-high-density

res/mipmap-mdpi/my_icon.png         // launcher icon for medium-density
res/mipmap-hdpi/my_icon.png         // launcher icon for high-density
res/mipmap-xhdpi/my_icon.png        // launcher icon for extra-high-density
res/mipmap-xxhdpi/my_icon.png       // launcher icon for extra-extra-high-density
res/mipmap-xxxhdpi/my_icon.png      // launcher icon for extra-extra-extra-high-density

代替リソースを使用する方法の詳細と設定修飾子の完全なリスト(画面設定用だけでなく)については、代替リソースを提供するを参照してください。

Android システムで実行時に使用するリソースが選択されるときは、特定のロジックによって「最適なリソース」が決定されることに注意してください。 つまり、システムで修飾子を使用するために、すべてのケースで、使用する修飾子が現在の画面設定に厳密に対応している必要はありません。 具体的には、サイズ修飾子に基づいてリソースを選択するときに、より適切なリソースがない場合は、現在の画面よりも小さな画面用に設計されたリソースが使用されます(たとえば、large(大)サイズの画面で、必要に応じて、normal(通常)サイズの画面用のリソースが使用されます)。 ただし、使用できるリソースが現在の画面用のリソースよりも大きなものしかない場合は、システムはそれらのリソースを使用しません。よって、その他のリソースが端末設定に一致しないときはアプリがクラッシュします(たとえば、すべてのレイアウト リソースに xlarge 識別子のタグが付いているが、端末は normal(通常)サイズの画面である場合) システムでリソースが選択される方法の詳細については、Android が最適なリソースを見つける仕組みを参照してください。

ヒント: システムでスケーリングしてはならないドローアブル リソースがある場合(実行時にデベロッパーが画像を調整する場合など)、nodpi 設定修飾子が付いたディレクトリにこれらのリソースを配置する必要があります。システムでは、この修飾子がタグ付けされたリソースは密度に依存しないと見なされ、スケーリングされません。

代替レイアウトとドローアブルの設計

作成する必要のある代替リソースのタイプはアプリのニーズよって異なります。通常、サイズの修飾子と画面の向きの修飾子を使用して、代替レイアウトのリソースを提供し、密度の修飾子を使用して、代替ビットマップ ドローアブルのリソースを提供します。

次のセクションでは、サイズの修飾子と密度の修飾子を使用して、代替レイアウトと代替ドローアブルをそれぞれ提供する方法について説明しています。

代替レイアウト

一般的に、異なる画面設定でアプリをテストすると、異なる画面サイズ用の代替レイアウトが必要かどうかが判明します。 次に例を示します。

  • small(小)画面でアプリをテストすると、その画面にレイアウトが収まらないことが判明する場合があります。 たとえば、small(小)画面の端末では、ボタンの行が画面幅の内側に収まらない場合があります。 この場合は、small(小)画面用の代替レイアウトを提供して、ボタンのサイズまたは位置を調整する必要があります。
  • extra-large(特大)画面でアプリをテストすると、レイアウトが大きな画面を効率的に活用しておらず、大きな画面を埋めるために引き伸ばされていることが明白になる場合があります。この場合は、extra-large(特大)画面用の代替レイアウトを提供して、タブレットなどの大きな画面向けに最適化および再設計された UI を適用する必要があります。

    代替レイアウトがなくても、大きな画面でアプリは適切に動作しますが、ユーザーにとっては、アプリがユーザーの端末向けに設計されているように見えることが重要になります。 UI が引き伸ばされていることが明らかな場合、ユーザーがアプリの使用感に満足しない可能性が高くなります。

  • 横向きの画面と縦向きの画面でアプリをテストすると、縦向きの画面の下部に配置された UI 要素が、横向きの画面では、画面の右側に表示されることが判明する場合があります。

まとめると、アプリのレイアウトは以下のようにする必要があります。

  • small(小)画面に収まる(ユーザーが実際にアプリを使用できるように)
  • 追加の画面スペースを活用するためにより大きな画面向けに最適化されている
  • 横向きの画面と縦向きの画面の両方に対して最適化されている

システムがレイアウト(ボタンの背景画像など)をスケーリングした後、ビューのサイズに合わせる必要のあるビットマップを UI で使用する場合は、9-patch ビットマップ ファイルを使用する必要があります。 9-patch ファイルは基本的に PNG ファイルであり、このファイルで、伸縮する 2 次元領域を指定します。 システムでビットマップが使用されるビューをスケーリングする必要がある場合、9-patch ビットマップが伸縮されますが、指定した領域のみが伸縮されます。 つまり、9-patch ビットマップはあらゆるサイズに適合できるため、異なる画面サイズに対して異なるドローアブルを提供する必要はありません。 ただし、異なる画面密度に対しては、9-patch ファイルの代替バージョンを提供する必要があります。

代替ドローアブル

図 4 各密度をサポートする、ビットマップ ドローアブルの相対サイズ。

ほぼすべてのアプリには、ランチャー アイコンがあり、このアイコンはすべての画面密度で適切に表示される必要があるため、アプリには、異なる画面密度向けの代替ドローアブル リソースが必要です。 同様に、アプリに他のビットマップ ドローアブル(アプリのメニュー アイコンやその他のグラフィックなど)を含めた場合、異なる画面密度向けに、各ドローアブルの代替バージョンを提供する必要があります。

注: ビットマップ ファイル(.png.jpg、または .gif)と 9-patch ファイル(.9.png)には密度固有のドローアブルのみを提供する必要があります。 形状、色、またはその他のドローアブル リソースを定義するために XML ファイルを使用している場合は、デフォルトのドローアブル ディレクトリ(drawable/)にこれらの XML ファイルのコピーを 1 つ配置する必要があります。

異なる密度用の代替ビットマップ ドローアブルを作成する場合は、6 つの汎用密度の比率 3:4:6:8:12:16 を適用する必要があります。 たとえば、中密度画面向けの 48x48 ピクセルのビットマップ ドローアブルの場合は、次のサイズにする必要があります。

  • 低密度では 36x36(0.75x)
  • 中密度では 48x48(1.0x 基準)
  • 高密度では 72x72(1.5x)
  • 超高密度では 96x96(2.0x)
  • 超超高密度では 144x144(3.0x)
  • 超超超高密度では 192x192(4.0x)(ランチャー アイコンのみ。上記のを参照)

アイコンの設計に関する詳細については、アイコンの設計ガイドラインを参照してください。このガイドラインには、ランチャー アイコン、メニュー アイコン、ステータスバー アイコン、タブ アイコンなどのビットマップ ドローアブルのサイズ情報が含まれています。

Android 3.2 のタブレット レイアウトの宣言

Android 3.0 を実行する第 1 世代のタブレットの場合、タブレット レイアウトを宣言する適切な方法は、xlarge 設定修飾子が付いたディレクトリ(たとえば、res/layout-xlarge/)にタブレット レイアウトを配置することでした。 他のタイプのタブレットや画面サイズ(特に 7 インチ タブレット)に対応するために、Android 3.2 では、個々の画面サイズ向けにリソースを指定する新しい方法が導入されました。 この新しい手法は、レイアウトを汎用サイズ グループ(large(大)や xlarge(特大)など)に適合させようとするのではなく、レイアウトが必要な領域(600dp の幅など)を基にしています。

汎用サイズ グループを使用すると、7 インチ タブレット向けの設計が難しくなる理由は、技術的には、7 インチ タブレットは 5 インチ ハンドセットと同じグループ(large(大)グループ)に属しているからです。 これらの 2 つの端末のサイズは同じように見えますが、ユーザー操作のスタイルの場合と同じように、アプリの UI 用の領域は大幅に異なっています。 したがって、7 インチ画面と 5 インチ画面で同じレイアウトを使用することはできません。 これらの 2 種類の画面に対して異なるレイアウトを提供できるようにするために、Android では現在、アプリのレイアウトで実際に使用できる dp 単位で指定された幅または高さに基づいて、レイアウト リソースを指定することができます。

たとえば、タブレット スタイルの端末で使いたいレイアウトを設計した場合、画面の幅が 600dp 未満のときに、レイアウトが適切に機能しないことが判明する場合があります。 したがって、このしきい値は、タブレットのレイアウトに必要な最小サイズになります。 つまり、アプリの UI が使用できる幅が 600dp 以上ある場合にのみ、これらのレイアウト リソースを使用する必要があることを指定できます。

レイアウトの最小サイズとして幅を選択して設計するか、設計の完了後、レイアウトがサポートする最小幅を特定するためのテストを実行する必要があります。

注: これらの新しいサイズの API で使用されるすべての数値は密度非依存ピクセル(dp)値であり、常に dp 単位を使用して(生ピクセル解像度を使用するのではなく)レイアウトの寸法を定義する必要があることに注意してください。つまり、システムが画面密度を認識した後で利用できる画面スペースについて考慮する必要があります。 密度非依存ピクセルの詳細については、このドキュメントで既に説明した用語とコンセプトを参照してください。

新しいサイズ修飾子の使用

表 2 では、レイアウトに使用可能なスペースに基づいて指定できるさまざまなリソース設定について説明しています。これらの新しい修飾子を使用すると、従来の画面サイズ グループ(small(小)、normal(通常)、large(大)、xlarge(特大))よりも、アプリでサポートする特定の画面サイズをさらに細かく制御できるようになります。

注: これらの修飾子を使用して指定するサイズは、実際の画面サイズではありません。 これらのサイズは、アクティビティ ウィンドウで使用できる dp 単位の幅または高さです。 Android システムでは、システム UI(画面下部のシステムバーや画面上部のステータスバーなど)用に画面の一部が使用される場合があるため、画面の一部がレイアウト向けに使用できないことがあります。 したがって、宣言するサイズは、アクティビティが必要とするサイズである必要があります。システムでは、レイアウトに割り当てるスペースを宣言すると、システム UI によって使用されるスペースが認識されます。また、レイアウトではアクションバーを宣言しませんが、アクションバーはアプリのウィンドウ スペースの一部であると見なされるため、レイアウト用に使用できるスペースが減少します。設計時はこのスペースの減少を考慮に入れる必要があることに注意してください。

表 2 画面サイズ用の新しい設定修飾子(Android 3.2 で導入)。

画面構成修飾子の値説明
smallestWidthsw<N>dp

例:
sw600dp
sw720dp

使用可能な画面領域の最小寸法で指定する、画面の基本サイズ。 具体的には、端末の smallestWidth は画面に使用できる高さと幅の最小サイズとなります(画面の「使用できる最小幅」と考えることもできます)。 画面の現在の方向に関係なく、この修飾子を使用することで、アプリの UI 用に少なくとも <N> dps の幅を使用できます。

たとえば、画面領域のレイアウトの最小寸法を常に 600 dp にする必要がある場合、この修飾子を使用してレイアウト リソース res/layout-sw600dp/ を作成できます。 システムは、600dp の側が縦になるか横になるか関係なく、使用可能な画面の最小寸法が 600dp 以上の場合にのみこれらのリソースを使用します。 smallestWidth は端末の固定された画面サイズ特性です。画面の向きが変わっても、端末の smallestWidth は変更されません。

端末の smallestWidth では画面の装飾とシステム UI が考慮されます。たとえば、端末の画面に smallestWidth の軸に沿ったスペースを考慮した固定 UI 要素がある場合、これらの画面ピクセルは UI に使用できないため、システムは実際の画面サイズよりも小さな smallestWidth を宣言します。

この修飾子は汎用画面サイズの修飾子(small、normal、large、xlarge)に替わるものであり、この修飾子を使用すると、UI 用に使用できる実際のサイズの個別の数値を定義することができます。多くの場合、レイアウトの設計では幅が重要な要素になるため、smallestWidth を使用して一般的な画面サイズを決定することは有用です。 多くの場合、UI は垂直にスクロールしますが、水平にスクロールする場合は、最小スペースの制約が厳しくなります。 また、使用可能な幅は、ハンドセット用に 1 ペイン レイアウトを使用するか、またはタブレット用にマルチペイン レイアウトを使用するかを決定する際の重要な要素になります。 したがって、各端末で使用できる最小幅を考慮することが最も重要になります。

使用できる画面の幅w<N>dp

例:
w720dp
w1024dp

リソースを使用する、使用可能な最小の幅を dp 単位で指定します。<N> の値で定義します。 幅に対応するシステムの値は、画面の向きを横向きまたは縦向きに切り替えたときに変更され、UI が使用できる現在の実際の幅が反映されます。

多くの場合、この機能は、マルチペイン レイアウトを使用するかどうかを決定する際に有用です。タブレット端末の場合でも、横向きの画面で使用したマルチペイン レイアウトと同じレイアウトを縦向きの画面では使用したくない場合があるからです。 したがって、画面サイズの修飾子と画面の向きの修飾子を併用する代わりに、この修飾子を使用して、レイアウトに必要な最小幅を指定することができます。

使用できる画面の高さh<N>dp

例:
h720dp
h1024dp
など

リソースを使用する、使用可能な最小の高さを dp 単位で指定します。<N> の値で定義します。 高さに対応するシステムの値は、画面の向きを横向きまたは縦向きに切り替えたときに変更され、UI が使用できる現在の実際の高さが反映されます。

画面サイズの修飾子と画面の向きの修飾子を使用する代わりに、w<N>dp を使用して必要な幅を定義した場合と同じように、この修飾子を使用して、レイアウトに必要な高さを定義することは有用です。ただし、多くの場合、UI は垂直にスクロールするため、使用できる高さに関してはより柔軟ですが、幅はより固定的であるため、ほとんどのアプリはこの修飾子を必要としません。

これらの修飾子を使用することは、画面サイズのグループを使用することよりも複雑に見えますが、実際には、UI の要件が定まっていればより簡単です。 多くの場合、UI を設計するときに最も重要になるのが、アプリでハンドセット スタイルの UI と複数のペインを使用するタブレット スタイルの UI を切り替える際の実際のサイズです。 この切り替えを行う際の厳密なサイズは、個々の設計によって異なります。たとえば、タブレット レイアウトに必要な幅は 720dp であったり、600dp または 480dp で十分であったり、720dp と 480dp の間の数値であったりさまざまです。 表 2 の修飾子を使用すると、レイアウトが変更される際の正確なサイズを制御することができます。

サイズの設定修飾子の詳細については、リソースの提供を参照してください。

設定の例

さまざまなタイプの端末向けに設計できるよう、通常の画面幅を以下に示します。

  • 320dp: 通常のスマートフォンの画面(240x320 ldpi、320x480 mdpi、480x800 hdpi など)。
  • 480dp: Streak などの小型タブレット(480x800 mdpi)。
  • 600dp: 7 インチ タブレット(600x1024 mdpi)。
  • 720dp: 10 インチ タブレット(720x1280 mdpi、800x1280 mdpi など)。

表 2 のサイズ修飾子を使用すると、幅または高さに必要な数値を使って、アプリでハンドセットやタブレットのさまざまなレイアウト リソースを切り替えることができます。 たとえば、タブレット レイアウトでサポートされる最小幅が 600dp の場合、次の 2 つのレイアウト セットを使用できます。

res/layout/main_activity.xml           # For handsets
res/layout-sw600dp/main_activity.xml   # For tablets

この場合、タブレット レイアウトを適用するには、使用できる画面スペースの最小幅は 600dp である必要があります。

7 インチ タブレットや 10 インチ タブレットなどのサイズ間で差別化するために、UI をさらにカスタマイズする場合は、次のような最小幅のレイアウトを追加で定義できます。

res/layout/main_activity.xml           # For handsets (smaller than 600dp available width)
res/layout-sw600dp/main_activity.xml   # For 7” tablets (600dp wide and bigger)
res/layout-sw720dp/main_activity.xml   # For 10” tablets (720dp wide and bigger)

上記のリソース例の 2 つのセットでは、「最小幅」の修飾子 sw<N>dp が使用されていることに注意してください。この修飾子は、端末の現在の向きに関係なく、画面の最小幅を指定します。 したがって、sw<N>dp を使用することは、画面の向きに関係なく、レイアウトで使用できる全体的な画面サイズを指定する最も簡単な方法です。

ただし、レイアウトで現在使用できる正確な幅または高さが重要になる場合があります。 たとえば、2 つのフラグメントが並べられた 2 ペイン レイアウトの場合、端末が横向きであるか縦向きであるかに関係なく、画面の幅が少なくとも 600dp のときは常にこのレイアウトを使用したい場合があるでしょう。 この場合、リソースは次のようになります。

res/layout/main_activity.xml         # For handsets (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml  # Multi-pane (any screen with 600dp available width or more)

2 番目のセットでは「使用できる幅」の修飾子 w<N>dp が使用されていることに注意してください。つまり、画面の向きに応じて、1 つの端末で両方のレイアウトを実際に使用できます(1 つの向きで使用できる最小幅が少なくとも 600dp であり、もう 1 方の向きで使用できる最小幅が 600dp 未満の場合)。

使用できる高さを考慮する必要がある場合は、h<N>dp 修飾子を使用して同じことができます。または、特定の設定が必要な場合は、w<N>dp 修飾子と h<N>dp 修飾子を組み合わせることができます。

画面サイズのサポートの宣言

さまざまな画面サイズ用のレイアウトを実装した後、アプリがサポートする画面をマニフェスト ファイルで宣言することが同様に重要になります。

Android 3.2 では、画面サイズ用の新しい設定修飾に加えて、<supports-screens> マニフェスト要素の属性が新たに導入されました。

android:requiresSmallestWidthDp
必要な最小 smallestWidth を指定します。smallestWidth は、アプリの UI に使用できる画面スペースの最短寸法(dp 単位)です。つまり、画面で使用できる幅または高さの最短寸法です。 したがって、端末がアプリと互換性があると見なされるには、端末の smallestWidth がこの値以上である必要があります (通常、smallestWidth に指定する値は、画面の現在の向きに関係なく、レイアウトがサポートする「最小幅」です)。

たとえば、使用可能な最小幅が 600dp のタブレット スタイルの端末に特化したアプリの場合は、次のようになります。

<manifest ... >
    <supports-screens android:requiresSmallestWidthDp="600" />
    ...
</manifest>

ただし、アプリが Android でサポートされるすべての画面サイズ(最小サイズは 426dp x 320dp)をサポートしている場合、アプリが要求する最小幅はすべての端末で使用可能な最小幅になるため、この属性を宣言する必要はありません。

警告: Android システムではこの属性が考慮されないため、この属性はアプリの実行時の動作に影響を及ぼしません。 その代わり、この属性は、Google Play などのサービスでアプリのフィルタリングを有効にするときに使用されます。 ただし、現在、Google Play はフィルタリング用のこの属性をサポートしていないため(Android 3.2 で)、アプリが小さな画面をサポートしていない場合は、他のサイズ属性を引き続き使用する必要があります。

android:compatibleWidthLimitDp
この属性を使用すると、アプリがサポートする最大の「最小」幅を指定することにより、画面互換性モードをユーザー オプション機能として有効にすることができます。 端末で使用可能な画面の最小幅がこの値よりも大きい場合、ユーザーはアプリをインストールできますが、画面互換性モードでアプリを実行するように求められます。 デフォルトでは、画面互換性モードは無効になっており、レイアウトは通常どおり画面に収まるようにサイズ変更され、システムバーには、ユーザーが画面互換性モードのオンとオフを切り替えることができるボタンが表示されます。

注: アプリのレイアウトが大きな画面用に適切にサイズ変更される場合は、この属性を使用する必要はありません。 この属性を使用せずに、このドキュメントにある推奨事項に従って、レイアウトが大きな画面用にサイズ変更されるようにすることをお勧めします。

android:largestWidthLimitDp
この属性を使用すると、アプリがサポートする最大の「最小」幅を指定することにより、画面互換性モードを強制的に有効にすることができます。 端末の使用可能な画面の最小幅がこの値よりも大きい場合、アプリは画面互換性モードで実行され、ユーザーは画面互換性モードを無効にできません。

注: アプリのレイアウトが大きな画面用に適切にサイズ変更される場合は、この属性を使用する必要はありません。 この属性を使用せずに、このドキュメントにある推奨事項に従って、レイアウトが大きな画面用にサイズ変更されるようにすることをお勧めします。

警告: Android 3.2 以降用のアプリを開発している場合、画面サイズの古い属性を上記の属性と組み合わせて使用しないでください。 新しい属性と古いサイズ属性の両方を使用すると、予期しない動作が発生する可能性があります。

これらの各属性に関する詳細については、上記のそれぞれのリンク先を参照してください。

ベスト プラクティス

複数の画面をサポートする目的は、Android でサポートされる汎用画面設定で適切に表示され、動作するアプリを作成することです。 このドキュメントの前のセクションでは、Android でアプリを画面設定に対応させる方法や、さまざまな画面設定でアプリの表示をカスタマイズする方法について説明しました。 このセクションでは、さまざまな画面設定に対してアプリを適切にスケーリングするための追加のヒントとその手法の概要について説明しています。

さまざまな画面でアプリを適切に表示する方法についての短いチェックリストを次に示します。

  1. XML レイアウト ファイルで寸法を指定するときは、wrap_contentmatch_parent、または dp 単位を使用する
  2. アプリのコードでハードコーディングされたピクセル値を使用しない
  3. AbsoluteLayout(サポート終了)を使用しない
  4. 異なる画面密度に対して代替ビットマップ ドローアブルを提供する

次のセクションで、さらに詳しく説明します。

1. レイアウト寸法に wrap_content、match_parent、または dp 単位を使用する

XML レイアウト ファイルのビューに対して android:layout_widthandroid:layout_height を定義するときに、"wrap_content""match_parent"、または dp 単位を使用すると、現在の端末画面でビューに適切なサイズが使用されます。

たとえば、layout_width="100dp" のビューは中密度画面では幅が 100 ピクセルになり、高密度画面では 150 ピクセルの幅にスケールアップされるため、ビューは、画面上でほぼ同じサイズの物理スペースを占めます。

同様に、テキストのサイズを定義するには、sp(スケール非依存ピクセル)を使用する必要があります。 sp スケール係数はユーザー設定に依存しており、システムにより、dp の場合と同じようにサイズがスケーリングされます。

2. アプリのコードでハードコーディングされたピクセル値を使用しない

パフォーマンス上の理由に加えて、コードをシンプルにするために、Android システムでは、寸法または座標の値を表すためにピクセルが標準の単位として使用されます。 つまり、ビューの寸法はコードで必ずピクセルで表記されますが、現在の画面密度に常に基づいています。たとえば、myView.getWidth() が 10 を返す場合、現在の画面ではビューの幅は 10 ピクセルですが、より高密度の画面を備えた端末では、返される値が 15 になる場合があります。 現在の画面密度向けに事前にスケーリングされていないビットマップを扱うために、アプリのコードでピクセル値を使用する場合、コードで使用するピクセル値をスケーリングして、スケーリングされていないビットマップ ソースに一致させる必要があることがあります。

アプリで実行時にビットマップを操作する場合、またはピクセル値を処理する場合は、密度に関する追加の考慮事項について説明している以下のセクションを参照してください。

3. AbsoluteLayout を使用しない

他のレイアウト ウィジェットとは異なり、AbsoluteLayout は強制的に固定位置を使用して子ビューを配置するため、異なる表示ではユーザー インターフェースが適切に機能しなくなる可能性が高くなります。 そのため、Android 1.5(API レベル 3)で AbsoluteLayout のサポートが終了しています。

その代わり、子ビューを配置するために相対配置を使用する RelativeLayout を使う必要があります。 たとえば、ボタン ウィジェットがテキスト ウィジェットの「右側」に表示されるように指定することができます。

4. サイズ固有および密度固有のリソースを使用する

システムでは、現在の画面設定に基づいてレイアウトとドローアブルがスケーリングされますが、異なる画面サイズに合わせて UI を調整し、異なる密度用に最適化されたビットマップ ドローアブルを提供する必要がある場合があります。 これは、このドキュメントで既に説明したことと基本的に同じです。

さまざまな画面設定でアプリがどのように表示されるかを厳密に制御する必要がある場合は、設定固有のリソース ディレクトリでレイアウトとビットマップ ドローアブルを調整します。 たとえば、中密度画面と高密度画面でアイコンを表示する必要があるとします。 この場合は、2 つの異なるサイズのアイコン(中密度画面用の 100x100 のアイコンと高密度画面用の 150x150 のアイコン)を作成し、適切な修飾子を使用して、これらのアイコンを次のような適切なディレクトリに配置します。

res/drawable-mdpi/icon.png   //for medium-density screens
res/drawable-hdpi/icon.png   //for high-density screens

注: ディレクトリ名で密度の修飾子が定義されていない場合、そのディレクトリ内のリソースは基準の中密度用に設計されていると判断され、必要に応じて、その他の密度用にスケーリングされます。

有効な設定修飾子の詳細については、このドキュメントで既に説明した設定修飾子の使用を参照してください。

密度に関する追加の考慮事項

このセクションでは、Android がさまざまな画面密度でビットマップ ドローアブルのスケーリングを実行する方法や、ビットマップがさまざまな密度で描画される際により詳細な制御を適用する方法について詳しく説明します。 なお、異なる画面密度でアプリを実行しているときや、アプリでグラフィックを操作しているときに問題が発生した場合を除いて、このセクションの情報は、ほとんどのアプリにおいて重要ではありません。

実行時にグラフィックを操作するときに複数の密度をサポートする方法をより深く理解するには、システムでは以下の方法でビットマップを適切にスケーリングできるようにしていることを把握する必要があります。

  1. リソースの事前スケーリング(ビットマップ ドローアブルなど)

    システムでは、現在の画面密度に基づいて、アプリのサイズ固有または密度固有のリソースを使用して、スケーリングを実行せずにこれらのリソースを表示します。 リソースが正しい密度で使用できない場合は、デフォルトのリソースが読み込まれ、必要に応じて、現在の画面密度に対応させるためにリソースがスケールアップまたはスケールダウンされます。 システムでは、密度固有のリソース ディレクトリからデフォルトのリソースが読み込まれた場合を除いて、デフォルトのリソース(設定修飾子が付いていないディレクトリからのリソース)は基準の画面密度(mdpi)向けに設計されていると判断されます。 したがって、ビットマップを現在の画面密度用の適切なサイズに変更するときに、システムで事前スケーリングが実行されます。

    事前にスケーリングされたリソースの寸法をリクエストすると、スケーリングを実行した後の寸法を表す値が返されます。 たとえば、mdpi 画面用に設計された 50x50 ピクセルのビットマップは、hdpi 画面では 75x75 ピクセルにスケーリングされ(hdpi 用の代替リソースがない場合)、システムはそのサイズを通知します。

    Android ではリソースを事前にスケーリングする必要がない場合があります。 事前スケーリングを回避する最も簡単な方法は、nodpi 設定修飾子が付いたリソース ディレクトリにリソースを配置することです。 次に例を示します。

    res/drawable-nodpi/icon.png

    システムがこのフォルダから icon.png ビットマップを使用するときは、現在の端末の密度に基づいてこのビットマップをスケーリングしません。

  2. ピクセルの寸法と座標の自動スケーリング

    マニフェストで android:anyDensity"false" に設定することにより、または Bitmap に対して、プログラムを使用して inScaled"false" に設定することにより、アプリで事前スケーリングを無効にできます。 この場合、システムは描画時にピクセルの絶対座標値とピクセルの寸法値を自動的にスケーリングします。 これにより、システムは、ピクセルで定義された画面要素が、基準の画面密度(mdpi)で表示される場合とほぼ同じ物理サイズで引き続き表示されるようにします。 このスケーリングはアプリに対して透過的に処理され、アプリには、ピクセルの物理的な寸法ではなく、スケーリングされたピクセルの寸法が通知されます。

    たとえば、端末が従来の HVGA 画面とほぼ同じ 480x800 のサイズの WVGA 高密度画面を備えているが、事前スケーリングを無効にしているアプリを実行しているとします。 この場合、システムは画面寸法を照会するとき、アプリに「嘘」をつき、320x533(画面密度のおおよその mdpi 変換)を通知します。 次に、アプリが (10,10) から (100,100) の四角形を無効化することなどの描画操作を実行するときに、システムは座標を適切にスケーリングすることにより座標を変換し、(15,15) から (150,150) の領域を実際に無効化します。 アプリがスケーリングされたビットマップを直接操作する場合は、この不一致により予期しない動作が発生する可能性がありますが、これは、アプリのパフォーマンスを可能な限り良好に維持するための妥当なトレードオフであると見なされます。 この状況が発生した場合は、次のセクションにある dp 単位からピクセル単位への変換を参照してください。

    通常は、事前スケーリングを無効にしないでください。複数の画面をサポートする最も良い方法は、上記の複数の画面をサポートする方法で説明した基本的な手法を活用することです。

アプリでビットマップを操作する場合、またはその他の方法で画面上のピクセルを直接操作する場合は、異なる画面密度をサポートするために、追加のステップを実行する必要がある場合があります。 たとえば、指でなぞったピクセルの数を数えることによってタッチ操作に応答する場合は、実際のピクセルではなく、適切な密度非依存ピクセルの値を使用する必要があります。

実行時に作成されるビットマップ オブジェクトのスケーリング

図 5 事前にスケーリングされたビットマップと自動的にスケーリングされたビットマップの比較。

アプリでメモリ内ビットマップ(Bitmap オブジェクト)を作成する場合、システムではデフォルトでそのビットマップが基準の中密度画面向けに設計されていると判断され、描画時にビットマップが自動的にスケーリングされます。 指定されていない密度プロパティがビットマップにある場合は、「自動スケーリング」が Bitmap に適用されます。現在の端末の画面密度を適切に把握しておらず、ビットマップの密度プロパティを指定していない場合、自動スケーリングにより、代替リソースを提供しなかったときと同じスケーリングの乱れが発生する可能性があります。

実行時に作成された Bitmap がスケーリングされるかどうかを制御するには、setDensity() を使用してビットマップの密度を指定し、DENSITY_HIGHDENSITY_LOW など、DisplayMetrics の密度定数を渡します。

ファイルやストリームから、BitmapFactory を使用して Bitmap を作成する場合は、BitmapFactory.Options を使用して既に存在しているビットマップのプロパティを定義することができます。これにより、システムでビットマップをスケーリングするかどうか、またはどのようにスケーリングするかが決定されます。 たとえば、inDensity フィールドを使用して、ビットマップを設計する密度を定義し、inScaled フィールドを使用して、現在の端末の画面密度に対応させるためにビットマップをスケーリングする必要があるかどうかを指定します。

inScaled フィールドを false に設定した場合は、システムがビットマップに適用する事前スケーリングを無効にしてください。そうすると、描画時にビットマップが自動的にスケーリングされます。 事前スケーリングの代わりに自動スケーリングを使用すると、CPU の負荷が高くなる場合がありますが、使用するメモリが少なくなります。 l

図 5 は、高密度画面で低密度(120)、中密度(160)、および高密度(240)のビットマップを読み込んだときの事前スケーリングおよび自動スケーリング メカニズムの結果を示しています。 すべてのビットマップが現在の画面密度に対応するようにスケーリングされているため、違いはわずかですが、ビットマップが事前にスケーリングされるか、描画時に自動的にスケーリングされるかに応じて、スケーリングされたビットマップは若干異なって表示されています。

注: Android 3.0 以降では、グラフィック フレームワークが改良されているため、事前にスケーリングされたビットマップと自動的にスケーリングされたビットマップの間に目に見える違いはありません。

dp 単位からピクセル単位への変換

寸法を dp 単位で表し、その後、ピクセル単位に変換する必要があることがあります。 ユーザーが指を少なくとも 16 ピクセル分動かすと、スクロール操作またはフリング操作が認識されるアプリがあるとします。 基準の画面では、操作が認識される前に、ユーザーは指を 1 インチの 1/10(2.5 mm)と同等の 16 pixels / 160 dpi 分動かす必要があります。高密度画面(240dpi)の端末では、ユーザーは指を 1 インチの 1/15(1.7 mm)と同等の 16 pixels / 240 dpi 分動かす必要があります。 高密度画面の場合、指を動かす距離がより短くなるため、ユーザーの操作に対してアプリがより敏感になるように見えます。

この問題を解決するには、コードで操作のしきい値を dp で表し、その後、実際のピクセルに変換します。 次に例を示します。

// The gesture threshold expressed in dp
private static final float GESTURE_THRESHOLD_DP = 16.0f;

// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels...

DisplayMetrics.density フィールドには、現在の画面密度に応じて、dp 単位をピクセルに変換するときに使用する必要のあるスケール係数を指定します。中密度画面では DisplayMetrics.density が 1.0、高密度画面では 1.5、超高密度画面では 2.0、低密度画面では 0.75 になります。 この数値は、現在の画面用の実際のピクセル数を取得するために dp 単位に掛ける必要のある係数です (次に、数値を整数に変換するときに、0.5f を足して最も近い整数に切り上げます)。詳細については、DisplayMetrics クラスを参照してください。

ただし、このようなケースでは任意のしきい値を定義する代わりに、ViewConfiguration から利用できる事前にスケーリングされた設定値を使用する必要があります。

事前にスケーリングされた設定値の使用

ViewConfiguration クラスを使用して、Android システムで使用する一般的な距離、速度、時間にアクセスすることができます。 たとえば、フレームワークでスクロールのしきい値として使用されるピクセル単位の距離は、getScaledTouchSlop() を使って取得できます。

private static final int GESTURE_THRESHOLD_DP = ViewConfiguration.get(myContext).getScaledTouchSlop();

getScaled 接頭辞で始まる ViewConfiguration のメソッドは、現在の画面密度に関係なく適切に表示されるピクセル単位の値を確実に返します。

複数の画面でアプリをテストする方法

図 6 画面のサポートをテストするための AVD のセット。

アプリを公開する前に、サポートされるすべての画面サイズと画面密度でアプリを十分にテストする必要があります。 Android SDK には、デベロッパーが使用できるエミュレータ スキンが含まれています。このエミュレータ スキンは、アプリが実行される可能性が高い一般的な画面設定のサイズと密度を再現します。 エミュレータ スキンのデフォルトのサイズ、密度、および解像度を変更し、特定の画面の特性を再現することもできます。 エミュレータ スキンと追加のカスタム設定を使用すると、可能なあらゆる画面設定をテストすることができます。アプリの画面サポートをテストするためだけに、さまざまな端末を購入する必要がなくなります。

アプリの画面サポートをテストするための環境をセットアップするには、アプリでサポートする予定の画面サイズと画面密度をエミュレートするエミュレータ スキンと画面設定を使用して、一連の AVD(Android Virtual Device)を作成する必要があります。 そのためには、AVD Manager を使用して AVD を作成し、グラフィカル インターフェースで AVD を起動します。

Android SDK Manager を起動するには、Android SDK ディレクトリから SDK Manager.exe を実行するか(Windows のみ)、<sdk>/tools/ ディレクトリから android を実行します(すべてのプラットフォーム)。 図 6 は、さまざまな画面設定をテストするための AVD を含む AVD Manager を示しています。

表 3 は、Android SDK で使用できるさまざまなエミュレータ スキンを示しています。これらのエミュレータ スキンを使用して、最も一般的ないくつかの画面設定をエミュレートすることができます。

アプリをテストするための AVD の作成および使用に関する詳細については、AVD Manager で AVD を管理するを参照してください。

表 3 Android SDK(太字表示)のエミュレータ スキンで使用できるさまざまな画面設定とその他の代表的な解像度。

低密度(120)、ldpi 中密度(160)、mdpi 高密度(240)、hdpi 超高密度(320)、xhdpi
小さな画面 QVGA(240x320)480x640
通常の画面 WQVGA400(240x400)
WQVGA432(240x432)
HVGA(320x480)WVGA800(480x800)
WVGA854(480x854)
600x1024
640x960
大きな画面 WVGA800**(480x800)
WVGA854**(480x854)
WVGA800*(480x800)
WVGA854*(480x854)
600x1024
特大の画面 1024x600WXGA(1280x800)
1024x768
1280x768
1536x1152
1920x1152
1920x1200
2048x1536
2560x1536
2560x1600
* この設定をエミュレートするには、WVGA800 または WVGA854 のスキンを使用する AVD を作成するときに、カスタム密度を 160 に指定します。
** この設定をエミュレートするには、WVGA800 または WVGA854 のスキンを使用する AVD を作成するときに、カスタム密度を 120 に指定します。
† このスキンは、Android 3.0 プラットフォームで使用できます。

任意の画面設定に対応するアクティブな端末を確認するには、画面サイズと密度のダッシュボードをご覧ください。

図 7 AVD Manager から AVD を起動するときに設定できるサイズと密度のオプション。

実際の端末とほぼ同じ物理サイズで実行するように設定されたエミュレータでアプリをテストすることもお勧めします。 これにより、非常に簡単に結果をさまざまなサイズと密度で比較できます。 そのためには、コンピュータのモニターのおおよその密度(dpi)を知る必要があります(たとえば、Dell の 30 インチ モニターの密度は約 96 dpi です)。 AVD Manager から AVD を起動するときに、図 7 に示されているように、[Launch Options] でエミュレータの画面サイズとモニターの dpi を指定することができます。

組み込みのスキンでサポートされていない解像度または密度を使用する画面上でアプリをテストするには、カスタムの解像度または密度を使用する AVD を作成します。 AVD Manager で AVD を作成するときに、組み込みのスキンを選択するのではなく、解像度を指定します。

コマンドラインから AVD を起動する場合は、-scale オプションを使ってエミュレータのスケールを指定できます。 次に例を示します。

emulator -avd <avd_name> -scale 96dpi

エミュレータのサイズを微調整するには、目的のスケーリング係数を表す 0.1 から 3 の数を -scale オプションに渡します。

コマンドラインからの AVD 作成に関する詳細については、コマンドラインから AVD を管理するを参照してください。