密度非依存ピクセル(DIP)について
dpは論理的なUI単位です。Vegaはこれをディスプレイのスケール係数を使用して物理ピクセルにマッピングします。単位変更の対象範囲
RN 0.83では、UIパス全体にdpマッピングが適用されます。- Vegaは最終的な描画キャンバスとダメージ領域をスケーリングします。
- ウィンドウのサイズと位置はグラフィックス境界を越える際に物理ピクセルになりますが、アプリコード内ではdpのままです。
- ポインター、タッチ、リサイズ、ウィンドウ位置、オクルージョンの各イベントはdpとしてReact Nativeに返されます。
- 子ウィンドウ、ポップアップ、モーダル、テクスチャキャッシュされたレイヤー、仮想サーフェスは、同じスケールを使用します。
DimensionsとuseWindowDimensions()は論理寸法を返します。PixelRatio.get()は、物理ピクセルとdpの比率を返します。
単位変更の対象ではないもの
以下の2つの領域では、既存の動作が維持されます。- ビットマップデータ。dpレンダリングはビットマップデータをスケーリングしたり、画像メタデータを変更したりしません。画像デコーダー、ビットマップ、ピクスマップ、テクスチャでは、引き続き物理ピクセル単位の寸法が使用されます。
- フォントのスケーリング。dpレンダリングは、アクセシビリティのフォントスケーリングに代わるものではありません。ユーザーが選択したテキストサイズについては、React NativeのテキストAPIと
fontScaleを引き続き使用してください。
PixelRatioとDeviceInfoターボモジュール
PixelRatioはReact Native JavaScriptユーティリティであり、スタンドアロンのターボモジュールではありません。PixelRatio.get()はDimensions.get('window').scaleを読み取ります。ネイティブのDeviceInfoターボモジュールは、width、height、scale、fontScaleをDimensionsに提供します。
RN 0.83では、DeviceInfoが論理ウィンドウ寸法(dp)と、現在の物理ピクセルからdpへのスケール値を報告します。また、didUpdateDimensionsを通じて、サーフェスごとの寸法の更新も公開します。
Vegaで密度非依存ピクセルを使用する理由
AndroidとiOS上のReact Nativeは、デフォルトで論理単位を使用します。VegaはRN 0.83アプリに同じデフォルト座標モデルを採用しているため、ジオメトリは3つのターゲットすべてで同じように動作します。 標準のReact Nativeコンポーネント、カスタムネイティブコンポーネント、ターボモジュール、サードパーティライブラリ、ウィンドウAPI、レンダリング、入力イベントは、1つの単位契約でカバーされるようになりました。アプリはUIジオメトリを論理単位で記述し、Vegaはそのジオメトリをグラフィック境界で変換します。UIの比率は、キャンバス解像度の異なるデバイス間で一定に保たれます。Scalable UIでは、個別のピクセルレイアウトなしで高解像度のキャンバスを選択できます。アプリでの変更
次の表は、一般的なRN 0.72のパターンとRN 0.83での動作の対応を示しています。ピクセル調整値の変換
RN 0.83では、数値の長さ指定はdpになります。移行前の基準となるスケール係数を使用して、物理ピクセルとして調整していた値を変換します。固定画面寸法の置き換え
ハードコーディングされた画面定数は、論理ビューポートを記述しません。代わりに実行時に寸法を読み取ってください。useWindowDimensions()は論理寸法を返します。React Nativeスタイルを割り当てる前に、それらを物理ピクセルに変換しないでください。
論理入力座標の使用
RN 0.83は、ポインター座標とタッチ座標をdp単位で返します。dp単位でのカスタムネイティブインターフェイスの保持
カスタムコンポーネントやターボモジュールのジオメトリは、React Nativeの境界でdpとして定義します。widthDpやtargetWidthPxのように、単位を名前に含めてください。
画像の処理
画像レイアウトと画像データは、異なる単位を使用します。<Image style={{width, height}}>ではdpが使用されます。- ソースビットマップの寸法、デコード後の画像寸法、行のバイト数、テクスチャの寸法には、物理ピクセルが使用されます。
- React Nativeが論理的なデコードサイズを指定した場合、Vegaの画像パイプラインはデコード前にその値にアクティブなスケール係数を乗算します。独自のコードでは、
<Image>スタイルや目的のレイアウトサイズに対して乗算処理を行わないでください。 - レンダリングされるdpサイズに対して、ソース画像には十分な物理ピクセルが必要になります。たとえば、320×180dpで描画され、スケール係数が2の場合、アップスケーリングを避けるには少なくとも640×360のソースピクセルが必要になります。
ローカルアセット
同じディレクトリ内に密度別のバリアントを配置してください。MetroとReact Nativeは、アクティブな密度に一致するアセットを選択します。@3xのデータを用意してください。React Nativeは、低解像度のソースをアップスケーリングする代わりに、より高解像度のアセットを選択します。アイコンやその他の写真以外のアートワークには、SVGを使用することをお勧めします。
移行チェックリスト
dpの移行を完了するには、次の手順を実行してください。- アプリをRN 0.83にアップグレードし、新しいデフォルト動作と重複するRN 0.72のdp実験用フラグをすべて削除します。
- アプリ内の数値による長さ指定、
1920や1080といった固定キャンバス定数、座標変換用のヘルパーをすべて確認します。 - 物理ピクセルとして調整されていた値は、
logicalValue = legacyPixelValue ÷ baselineScaleFactorの式で論理値に変換します。密度非依存のUX仕様に由来する値は、変更せずにそのまま残してください。 - RN 0.83によって報告されるポインター、ジェスチャー、スクロール、リサイズ、ウィンドウの座標は、dpとして扱います。
- React-Nativeからネイティブへのカスタムジオメトリコントラクトをdpに変更し、ドキュメント化されたピクセルAPIでのみピクセル変換を維持します。
- 固定画面寸法をFlexbox、パーセンテージ、
Dimensions、useWindowDimensions()を使用して置き換えます。 - ローカルのラスター密度バリアントを追加し、各画像が論理サイズで描画される際に十分な物理ピクセルを持っていることを確認します。
- メインウィンドウ、モーダル、ポップアップ、アラート、子ウィンドウ、スクロール、ジェスチャー、フォーカス、アクセシビリティ、ローカリゼーション、右から左へのレイアウトを、サポートされている各密度でテストします。
関連トピック
- 手順4:コードを移行する
- React Native 0.83へのアプリの移行
- PixelRatio
- useWindowDimensions
- レイアウトの測定(英語のみ)
- React Native 0.83への移行に関する問題のトラブルシューティング
外部リソース
- React Native PixelRatio(英語のみ)
- React Native Images(英語のみ)

