モバイルアプリケーションでの複数のスクリーンサイズと DPI 値のサポート

複数のスクリーンサイズと DPI 値をサポートするためのガイドライン

プラットフォームに依存しないアプリケーションを開発するには、様々な出力デバイスがあることに注意する必要があります。デバイスには様々なスクリーンサイズや解像度、および様々な DPI 値や密度があります。

Flex エンジニアの Jason SJ が、解像度に依存しないモバイルアプリケーションを作成するための 2 つのアプローチについてブログで説明しています。

用語集

解像度とは、高さのピクセル数 x 幅のピクセル数のことで、デバイスがサポートする合計ピクセル数のことです。

DPI とは、平方インチ当たりのドット数のことで、デバイススクリーンのピクセルの密度のことです。 DPI という用語は、PPI(pixels per inch)と同じ意味です。

DPI に対する Flex のサポート

Flex の次の機能を使用すると、解像度や DPI に依存しないアプリケーションを作成するプロセスを簡素化できます。

スキン
モバイルコンポーネントのための DPI を認識するスキン。デフォルトのモバイルスキンでは、多くのデバイスの解像度に合わせて拡大/縮小するための追加のコーディングが必要ありません。

applicationDPI
カスタムスキンのデザインサイズを定義するプロパティ。このプロパティを特定の DPI に設定して、ユーザーが異なる DPI 値のデバイスでアプリケーションを実行したとします。 Flex では、使用中のデバイスの DPI に合わせてアプリケーションのすべての内容が拡大/縮小されます。

デフォルトのモバイルスキンは DPI に依存しないスキンです。DPI スケーリングを使用する場合もしない場合もあります。したがって、静的なサイズまたはカスタムスキンのコンポーネントを使用しない場合は、通常、applicationDPI プロパティを設定する必要はありません。

動的なレイアウト

異なる解像度に対応するには、動的なレイアウトを使用するのが効果的です。例えば、コントロールの幅を 100 %に設定すると、解像度が 480x854 の場合も 480x800 の場合も、解像度に関係なく常にスクリーンの幅全体に表示されるようになります。

applicationDPI プロパティの設定

密度に依存しないアプリケーションを作成する際には、ルートアプリケーションタグにターゲット DPI を設定できます。(モバイルアプリケーションの場合、ルートタグは、<s:ViewNavigatorApplication><s:TabbedViewNavigatorApplication> または <s:Application> です。)

applicationDPI プロパティの値は、ターゲットデバイスのおおよその解像度に従って、160、240 または 320 に設定します。次に例を示します。
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    firstView="views.DensityView1" 
    applicationDPI="320">

applicationDPI プロパティを設定すると、実行時にターゲットデバイスの実際の解像度(runtimeDPI)と比較される際に、アプリケーションに対する拡大/縮小が効率的に定義されます。例えば、applicationDPI プロパティを 160 に設定し、ターゲットデバイスの runtimeDPI が 160 の場合、スケール比率は 1(拡大/縮小なし)となります。applicationDPI プロパティを 240 に設定した場合、スケール比率は 1.5(すべての表示を 150 %に拡大)になります。320 の場合、スケール比率は 2 になるので、すべての表示が 200 %に拡大されます。

スケール比率が整数でない場合、補間により、線が不明確になるなどの好ましくないアーティファクトが表示される場合があります。

DPI スケーリングの無効化

アプリケーションの DPI スケーリングを無効にする場合は、applicationDPI プロパティの値を設定しません。

applicationDPI と runtimeDPI について

次の表では、異なる解像度でアプリケーションを操作する際に必要な Application クラスの 2 つのプロパティについて説明します。

プロパティ

説明

applicationDPI

アプリケーションのターゲット解像度または DPI。

このプロパティに値を指定すると、ルートアプリケーションにスケール比率が適用されます。そのため、1 つの DPI 値に対してデザインされたアプリケーションが、DPI 値が異なる別のデバイスでも美しく表示されるように拡大/縮小されます。

スケール比率は、このプロパティと runtimeDPI プロパティの値を比較して計算されます。このスケール比率は、プリローダー、ポップアップおよびステージ上のすべてのコンポーネントを含めたアプリケーション全体に適用されます。

値が指定されていない場合、このプロパティは runtimeDPI プロパティと同じ値を返します。

このプロパティは、ActionScript では設定できません。MXML でのみ設定できます。このプロパティの値を実行時に変更することはできません。

runtimeDPI

アプリケーションを現在実行しているデバイスの解像度または DPI 値。

DPIClassification クラスで定義された定数の 1 つに端数処理した Capabilities.screenDPI プロパティの値を返します。

このプロパティは読み取り専用です。

解像度や DPI に依存しないアプリケーションの作成

解像度や DPI に依存しないアプリケーションは、次の特性を備えています。
画像
ベクトル形式の画像は、ターゲットデバイスの実際の解像度に合わせてスムーズに拡大/縮小されます。一方、ビットマップの場合はスムーズに拡大/縮小できない可能性があります。このような場合は、MultiDPIBitmapSource クラスを使用して、デバイスの解像度に応じた様々な解像度のビットマップを読み込めます。

テキスト
テキストのフォントサイズ(テキスト自体ではなく)は、解像度に合わせて拡大/縮小されます。

レイアウト
動的レイアウトを使用して、拡大/縮小時にアプリケーションが適切に表示されるようにします。一般に、絶対値を使用してピクセル境界を指定するような制約のあるレイアウトの使用は避けてください。制約を使用する必要がある場合は、applicationDPI プロパティの値を使用して拡大/縮小を考慮します。

拡大/縮小
scaleX および scaleY プロパティを Application オブジェクトで使用しないでください。 applicationDPI プロパティを設定すると、Flex で拡大/縮小が処理されます。

スタイル
スタイルシートを使用して、ターゲットデバイスの OS およびアプリケーションの DPI 設定のスタイルプロパティをカスタマイズできます。

スキン
Flex のモバイルテーマのスキンは、アプリケーションの DPI 値を使用して、実行時に使用するアセットを判断します。FXG ファイルで定義された視覚的なスキンアセットはすべて、ターゲットデバイスに合うように調整されます。

アプリケーションサイズ
アプリケーションの高さと幅は明示的に設定しないでください。また、カスタムコンポーネントまたはポップアップのサイズを計算する場合は、stageWidth プロパティと stageHeight プロパティを使用しないでください。代わりに、SystemManager.screen プロパティを使用します。

実行時 DPI の判断

アプリケーションが起動されると、アプリケーションは Capabilities.screenDPI という Flash Player のプロパティから runtimeDPI プロパティの値を取得します。このプロパティは、DPIClassification クラスで定義された定数の 1 つにマップされます。例えば、232 DPI で動作している Droid は、240 の実行時 DPI 値にマップされます。デバイスの DPI 値は、DPIClassification 定数(160、240 または 320)といつも正確に一致するわけではありません。 ターゲット値の範囲に基づいて、定数の分類にマップされます。

次のようにマップされます。

DPIClassification 定数

160 DPI

240 DPI

320 DPI

デバイスの実際の DPI

<200

>=200 かつ <280

>=280

これらのマッピングをカスタマイズして、デフォルトの動作をオーバーライドしたり、DPI 値を正しく取得できないデバイスを調整することができます。詳しくは、デフォルト DPI のオーバーライドを参照してください。

自動サイズ変更の有無の選択

applicationDPI プロパティの値を設定して)自動サイズ変更を使用するかどうかは、便利さを優先するか、ピクセルレベルで視覚的な忠実度を優先するかの兼ね合いで決めます。 applicationDPI プロパティを設定して、アプリケーションを自動サイズ変更する場合は、applicationDPI をターゲットとするスキンが使用されます。スキンは、デバイスの実際の密度に合うように拡大/縮小されます。アプリケーションの他のアセットとレイアウト位置も拡大/縮小されます。

自動サイズ変更を使用する場合に、1 つの DPI 値をターゲットとするスキンやアセットを作成している場合は、通常次のようにします。
  • 指定する applicationDPI をターゲットとするスキンとビュー/コンポーネントのレイアウトのセットを 1 つ作成します。

  • アプリケーションのスキンまたは他の場所で使用するビットマップアセットの複数のバージョンを作成し、MultiDPIBitmapSource クラスを使用して指定します。自動サイズ変更を使用する場合、スキンのベクトルアセットとテキストで密度を意識する必要はありません。

  • アプリケーションでは 1 つのターゲット DPI 値のみが考慮されているので、@media ルールをスタイルシートで使用しないでください。

  • 様々な密度のデバイスでアプリケーションをテストして、拡大/縮小されたアプリケーションが各デバイスで適切に表示されることを確認します。特に、整数ではない比率で拡大/縮小されるデバイスを確認してください。例えば、applicationDPI が 160 の場合は、240 DPI のデバイスでアプリケーションをテストしてください。

自動サイズ変更をしない(applicationDPI プロパティを設定しない)場合は、applicationDPI の値を取得します。 このプロパティを使用して、デバイスの実際の DPI の分類を判断し、次のようにして実行時にアプリケーションを適合させます。
  • 実行時 DPI の各分類を対象にして、スキンとレイアウトのセットを複数作成するか、様々な密度に動的に適合するスキンとレイアウトのセットを 1 つ作成します。(Flex プリセットのスキンでは、後者の方法を採用しています。各スキンクラスが、applicationDPI プロパティを確認して自分自身を適切に設定します。)

  • @media ルールをスタイルシートで使用すると、デバイスの DPI の分類に基づいて CSS ルールにフィルターをかけることができます。通常は、各 DPI 値に対して、フォントサイズとパディング値をカスタマイズします。

  • 様々な密度のデバイスでアプリケーションをテストして、スキンとレイアウトが正しく調整されることを確認します。

DPI に基づいたスタイルの選択

Flex では、CSS を使用して、ターゲットの OS とアプリケーション DPI 値に基づいたスタイルを適用できます。スタイルシートの @media ルールを使用してスタイルを適用します。@media ルールは CSS 仕様の一部です。Flex ではこのルールを拡張し、application-dpi および os-platform という追加のプロパティを挿入します。これらのプロパティを使用して、アプリケーションの DPI とアプリケーションが実行されているプラットフォームに基づいて、スタイルを選択的に適用します。

次の例では、Spark Button コントロールのデフォルトの fontSize スタイルプロパティを 12 に設定します。デバイスで 240 DPI が使用され、Android オペレーティングシステムで実行されている場合、fontSize プロパティは 10 となります。
<?xml version="1.0" encoding="utf-8"?>
<!-- mobile_skins/MediaQueryValuesMain.mxml -->
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
     xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="320">
    
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/mx";

        s|Button {
            fontSize: 12;
        }

        @media (os-platform: "Android") and (application-dpi: 240) {
            s|Button {
                fontSize: 10;
            }
        }

    </fx:Style>
    
</s:ViewNavigatorApplication>

application-dpi プロパティの値

CSS の application-dpi プロパティは、ルートアプリケーションに設定されている applicationDPI スタイルプロパティの値と比較されます。CSS の application-dpi プロパティに有効な値は次のとおりです。
  • 160

  • 240

  • 320

application-dpi でサポートされている各値には、DPIClassification クラスに対応する定数があります。

os-platform プロパティの値

CSS の os-platform プロパティは、Flash Player の flash.system.Capabilities.version プロパティの値に相当します。CSS の os-platform プロパティに有効な値は次のとおりです。
  • Android

  • iOS

  • Macintosh

  • Linux

  • QNX

  • Windows

大文字と小文字が異なっても一致します。

どのエントリも一致しない場合、サポートされるプラットフォームのリストの最初の 3 文字を比較して、二次的な一致を探します。

application-dpi および os-platform プロパティのデフォルト

application-dpi プロパティまたは os-platform プロパティが含まれている式を明示的に定義していない場合は、すべての式が一致していると見なされます。

@media ルールの演算子

@media ルールには「and」および「not」の一般的な演算子を使用できます。カンマ区切りのリストもサポートされています。式をカンマで区切ると、「or」条件になります。

「not」演算子使用する際には、「not」を式の最初のキーワードにする必要があります。この演算子は、「not」に続くプロパティだけでなく式全体を否定します。バグ SDK-29191 があるので、「not」演算子の後には、「all」などのメディアタイプを式の前に指定する必要があります。

次の例は、これらの一般的な演算子の使用方法を示しています。
<?xml version="1.0" encoding="utf-8"?>
<!-- mobile_skins/MediaQueryValuesMain.mxml -->
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
     xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="320">
    
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/mx";

        /* Every os-platform @ 160dpi */
        @media (application-dpi: 160) {
            s|Button {
                fontSize: 10;
            }
        }

        /* IOS only @ 240dpi */
        @media (application-dpi: 240) and (os-platform: "IOS") {
            s|Button {
                fontSize: 11;
            }
        }

        /* IOS at 160dpi or Android @ 160dpi */
        @media (os-platform: "IOS") and (application-dpi:160), (os-platform: "ANDROID") and (application-dpi: 160) {
            s|Button {
                fontSize: 13;        
            }
        }

        /* Every os-platform except Android @ 240dpi */
        @media not all and (application-dpi: 240) and (os-platform: "Android") {
            s|Button {
                fontSize: 12;
            }
        }    

        /* Every os-platform except IOS @ any DPI */
        @media not all and (os-platform: "IOS") {
            s|Button {
                fontSize: 14;        
            }
        }
    </fx:Style>
    
</s:ViewNavigatorApplication>

DPI に基づいたビットマップアセットの選択

通常、ビットマップ画像のアセットは、デザインされている解像度でのみ最適にレンダリングされます。この制限により、複数の解像度を対象としたアプリケーションをデザインする場合は、多少の困難を伴う可能性があります。解決策としては、複数(異なる解像度ごとに 1 つ)のビットマップを作成して、アプリケーションの runtimeDPI プロパティの値に従って、適切なビットマップを読み込みます。

Spark の BitmapImage コンポーネントと Image コンポーネントには、Object タイプの source プロパティがあります。このプロパティがあるので、どのアセットを使用するかを定義したクラスを渡すことができます。この場合は、runtimeDPI プロパティの値に従って異なるソースをマップするように、MultiDPIBitmapSource クラスを渡します。

次の例では、DPI に従って異なる画像を読み込みます。
<?xml version="1.0" encoding="utf-8"?>
<!-- mobile_skins/views/MultiSourceView3.mxml -->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        title="Image with MultiDPIBitmapSource">

    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    
    <fx:Script>
        <![CDATA[
            import mx.core.FlexGlobals;
            
            private function doSomething():void {
                /* The MultiDPIBitmapSource's source data. */
                myTA.text = myImage.source.getSource(FlexGlobals.topLevelApplication.applicationDPI).toString();            
            }
            
            
        ]]>
    </fx:Script>

    <s:Image id="myImage">
        <s:source>
            <s:MultiDPIBitmapSource
                    source160dpi="assets/low-res/bulldog.jpg"
                    source240dpi="assets/med-res/bulldog.jpg"
                    source320dpi="assets/high-res/bulldog.jpg"/>
        </s:source>
    </s:Image>

    <s:Button id="myButton" label="Click Me" click="doSomething()"/>
    <s:TextArea id="myTA" width="100%"/>

</s:View>

デスクトップアプリケーションで MultiDPIBitmapSource が指定されている BitmapImage クラスおよび Image クラスを使用すると、ソースには source160dpi プロパティが使用されます。

Button コントロールの icon プロパティにも、クラスが引数として使用されます。したがって、MultiDPIBitmapSource オブジェクトを Button のアイコンのソースとして使用することもできます。アイコンのソースは、次の例に示すようにインラインで定義できます。
<?xml version="1.0" encoding="utf-8"?>
<!-- mobile_skins/views/MultiSourceView2.mxml -->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" title="Icons Inline">

    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    
    <fx:Script>
        <![CDATA[
            import mx.core.FlexGlobals;
            
            private function doSomething():void {                
                /* The MultiDPIBitmapSource's source data. */
                myTA.text = dogButton.getStyle("icon").getSource(FlexGlobals.topLevelApplication.applicationDPI).toString();
            }
        ]]>
    </fx:Script>

    <s:Button id="dogButton" click="doSomething()">
        <s:icon>
            <s:MultiDPIBitmapSource id="dogIcons"
                    source160dpi="@Embed('../../assets/low-res/bulldog.jpg')"
                    source240dpi="@Embed('../../assets/med-res/bulldog.jpg')"
                    source320dpi="@Embed('../../assets/high-res/bulldog.jpg')"/>
        </s:icon>
    </s:Button>       
    <s:TextArea id="myTA" width="100%"/>

</s:View>
次の例に示すように、<fx:Declarations> ブロックでアイコンを宣言し、データバインディングを使用してソースを割り当てて、アイコンを定義することもできます。
<?xml version="1.0" encoding="utf-8"?>
<!-- mobile_skins/views/MultiSourceView1.mxml -->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:mx="library://ns.adobe.com/flex/mx"
        xmlns:s="library://ns.adobe.com/flex/spark" 
        title="Icons in Declarations">

    <fx:Declarations>
        <s:MultiDPIBitmapSource id="dogIcons"
                source160dpi="@Embed('../../assets/low-res/bulldog.jpg')"
                source240dpi="@Embed('../../assets/med-res/bulldog.jpg')"
                source320dpi="@Embed('../../assets/high-res/bulldog.jpg')"/>
    </fx:Declarations>

    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    
    <fx:Script>
        <![CDATA[
            import mx.core.FlexGlobals;
            
            private function doSomething():void {                
                /* The MultiDPIBitmapSource's source data. */
                myTA.text = dogIcons.getSource(FlexGlobals.topLevelApplication.applicationDPI).toString();
            }
        ]]>
    </fx:Script>

    <s:Button id="dogButton" icon="{dogIcons}" click="doSomething()"/>    
    <s:TextArea id="myTA" width="100%"/>    
</s:View>

runtimeDPI プロパティが null または空の文字列("")の sourceXXXdpi プロパティにマップしている場合、Flash Player では、次に高い解像度のプロパティがソースとして使用されます。その値も null または空の場合は、次に低い解像度が使用されることになります。その値null または空の場合は、null がソースとして割り当てられて、画像は表示されません。つまり、画像を特定の DPI で表示しないという明示的な指定はできません。

DPI に基づいたスキンアセットの選択

デフォルトモバイルスキンのコンストラクターのロジックでは、applicationDPI プロパティの値に基づいてアセットが選択されます。これらのクラスでは、ターゲット DPI 値に最も近いアセットが選択されます。DPI スケーリングを使用する場合もしない場合も機能するカスタムスキンをデザインする場合は、applicationDPI プロパティを使用し、runtimeDPI プロパティは使用しません。

例えば、spark.skins.mobile.ButtonSkin クラスでは、次のように、特定の DPI 値用にデザインされている FXG アセットを選択する switch/case 文を使用します。
switch (applicationDPI) { 
    case DPIClassification.DPI_320: { 
        upBorderSkin = spark.skins.mobile320.assets.Button_up; 
        downBorderSkin = spark.skins.mobile320.assets.Button_down; 
        ... 
        break; 
    } 
    case DPIClassification.DPI_240: { 
        upBorderSkin = spark.skins.mobile240.assets.Button_up; 
        downBorderSkin = spark.skins.mobile240.assets.Button_down; 
        ... 
        break; 
    } 
}

FXG アセットを条件付きで選択することに加え、モバイルのスキンクラスでは、レイアウトの間隔やレイアウトのパディングなど、他のスタイルプロパティ値も設定します。これらの設定は、ターゲットデバイスの DPI に基づいています。

applicationDPI を設定しない場合

applicationDPI プロパティを設定していない場合、スキンは runtimeDPI プロパティを使用するようにデフォルト設定されます。このメカニズムでは、runtimeDPI プロパティではなく、applicationDPI プロパティの値に基づくスキンに対して、DPI スケーリングを使用する場合もしない場合も適切なリソースが使用されるようになります。

カスタムスキンを作成している場合は、applicationDPI 設定を無視するように選択できます。その結果、ターゲットデバイスの DPI に合うように拡大/縮小されるスキンになります。ただし、アセットがその DPI 値用に特にデザインされていない場合は、最適な表示にならない可能性があります。

CSS の applicationDPI を使用する場合

カスタムスキンを作成せずに、CSS の @media セレクターで applicationDPI プロパティの値を使用して、モバイルアプリケーションやタブレットアプリケーションで使用されるスタイルをカスタマイズします。詳しくは、DPI に基づいたスタイルの選択を参照してください。

スケール比率と現在の DPI の手動による判断

モバイルアプリケーションやタブレットアプリケーションがターゲットデバイスの DPI 値に基づいて選択するアセットを手動で指定するには、実行時にスケール比率を計算します。スケール比率は、runtimeDPI プロパティの値を applicationDPI スタイルプロパティの値で除算して計算します。

import mx.core.FlexGlobals; 
var curDensity:Number = FlexGlobals.topLevelApplication.runtimeDPI; 
var curAppDPI:Number = FlexGlobals.topLevelApplication.applicationDPI; 
var currentScalingFactor:Number = curDensity / curAppDPI;
計算したスケール比率を使用して、アセットを手動で選択できます。次の例では、ビットマップアセットの場所を DPI 値ごとに定義します。次に、その場所から画像を読み込みます。
<?xml version="1.0" encoding="utf-8"?>
<!-- mobile_skins/DensityMain.mxml -->
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
     xmlns:s="library://ns.adobe.com/flex/spark" 
     firstView="views.DensityView1" 
     applicationDPI="240" initialize="initApp()">
    
    <fx:Script>
        <![CDATA[
                [Bindable]
                public var densityDependentDir:String;

                [Bindable]
                public var curDensity:Number;
                [Bindable]
                public var appDPI:Number;
                [Bindable]
                public var curScaleFactor:Number;
                
                public function initApp():void {
                    curDensity = runtimeDPI; 
                    appDPI = applicationDPI;
                    curScaleFactor  =  appDPI / curDensity;

                    switch (curScaleFactor) {
                        case 1: { 
                            densityDependentDir = "../../assets/low-res/"; 
                            break; 
                        } 
                        case 1.5: { 
                            densityDependentDir = "../../assets/med-res/"; 
                            break;
                        }
                        case 2: { 
                            densityDependentDir = "../../assets/high-res/"; 
                            break;
                        }                
                    }
                }   
        ]]>
    </fx:Script>
    
</s:ViewNavigatorApplication>
スケール比率を使用するビューは次のとおりです。
<?xml version="1.0" encoding="utf-8"?>
<!-- mobile_skins/views/DensityView1.mxml -->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        title="Home" 
        creationComplete="initView()">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    
    <fx:Script>
        <![CDATA[
            import mx.core.FlexGlobals;

            [Bindable]
            public var imagePath:String;

            private function initView():void {
                label0.text = "App DPI:" + FlexGlobals.topLevelApplication.appDPI;
                label1.text = "Cur Density:" + FlexGlobals.topLevelApplication.curDensity;
                label2.text = "Scale Factor:" + FlexGlobals.topLevelApplication.curScaleFactor;         

                imagePath = FlexGlobals.topLevelApplication.densityDependentDir + "bulldog.jpg";
                
                ta1.text = myImage.source.toString();
            }
        ]]>
    </fx:Script>
    
    <s:Image id="myImage" source="{imagePath}"/>

    <s:Label id="label0"/>
    <s:Label id="label1"/>
    <s:Label id="label2"/>

    <s:TextArea id="ta1" width="100%"/>
</s:View>

デフォルト DPI のオーバーライド

アプリケーションの DPI 値を設定すると、実行しているデバイスからの DPI 値に基づいてアプリケーションが拡大/縮小されます。場合によっては、デバイスから不適切な DPI 値が報告されることや、カスタムの拡大/縮小方法を採用してデフォルトの DPI 選択方法をオーバーライドすることがあります。

デフォルトの DPI マッピングをオーバーライドすることで、アプリケーションのデフォルトの拡大/縮小動作をオーバーライドできます。例えば、デバイスから 160 ではなく 240 の DPI であると不適切な情報が届く場合は、このデバイスを見つけて、160 の DPI として分類するカスタムマッピングを作成できます。

特定のデバイスの DPI 値をオーバーライドするには、Application クラスの runtimeDPIProvider プロパティが RuntimeDPIProvider クラスのサブクラスを指し示すようにします。サブクラスで、runtimeDPI という getter をオーバーライドし、カスタム DPI マッピングを提供するロジックを追加します。UIComponent などのフレームワークの他のクラスに依存関係を追加しないでください。 このサブクラスは Player API にのみ呼び出すことができます。

次の例では、Capabilities.os プロパティが「Mac 10.6.5」に該当するデバイスについて、カスタム DPI マッピングを設定します。
package {
import flash.system.Capabilities;
import mx.core.DPIClassification;
import mx.core.RuntimeDPIProvider;

public class DPITestClass extends RuntimeDPIProvider {
    public function DPITestClass() {
    }
    
    override public function get runtimeDPI():Number {
        // Arbitrary mapping for Mac OS.
        if (Capabilities.os == "Mac OS 10.6.5")
            return DPIClassification.DPI_320;
        
        if (Capabilities.screenDPI < 200)
            return DPIClassification.DPI_160;
        
        if (Capabilities.screenDPI <= 280)
            return DPIClassification.DPI_240;
        
        return DPIClassification.DPI_320; 
    }
}
}
次のアプリケーションでは、DPITestClass を使用して、拡大/縮小に使用する実行時の DPI 値を決定しています。この例では、ViewNavigatorApplication クラスの runtimeDPIProvider プロパティを指しています。
<?xml version="1.0" encoding="utf-8"?>
<!-- mobile_skins/DPIMappingOverrideMain.mxml -->
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
     xmlns:s="library://ns.adobe.com/flex/spark" 
     firstView="views.DPIMappingView" 
     applicationDPI="160"
     runtimeDPIProvider="DPITestClass">
        
</s:ViewNavigatorApplication>
次に、RuntimeDPIProvider クラスのサブクラスについて別の例を示します。この例では、カスタムクラスがデバイスのスクリーンの幅と高さの解像度をチェックして、デバイスが不適切な DPI 値を報告しているかどうかを判断します。
package
{
import flash.system.Capabilities;
import mx.core.DPIClassification;
import mx.core.RuntimeDPIProvider;

public class SpecialCaseMapping extends RuntimeDPIProvider {
    public function SpecialCaseMapping() {
    }
    
    override public function get runtimeDPI():Number {
        /* A tablet reporting an incorrect DPI of 240. We could use
            Capabilities.manufacturer to check the tablet's OS as well. */
        if (Capabilities.screenDPI == 240 && 
            Capabilities.screenResolutionY == 1024 && 
            Capabilities.screenResolutionX == 600) {
            return DPIClassification.DPI_160;
        }
        
        if (Capabilities.screenDPI < 200)
            return DPIClassification.DPI_160;
        
        if (Capabilities.screenDPI <= 280)
            return DPIClassification.DPI_240;
        
        return DPIClassification.DPI_320; 
    }
}
}