AndroidのDimension

前置き

Androidプログラミングで、Dimension(寸法)を指定するときの単位に関する話しをまとめます。

本文

製品によるドット密度の違い

製品サイズ(インチ)解像度ドット密度(dpi)ドットピッチ(mm)
Pocket WiFi S(S31HW)2.8320x2401430.178
T-Mobile G13.2480x3201800.144
Xperia arc SO-01C4.2854x4802330.109
Motorola Atrix 4G4960x5402750.092

製品の選び方に他意はないです。

Androidでのドット密度の分類

4つに分かれるようです。

分類ドット密度の目安(dpi)標準アイコンサイズ(ドット)
ldpi~12032x32
mdpi~16048x48
hdpi~24072x72
xhdpi~32096x96

単位

名前意味
ptポイント。1ptは1/72インチ。約0.35mmです。
pxピクセル。1ピクセルは1ドットですね。
mmミリ。
inインチ。1インチは約25.4mmです。
dp/dipドット密度の違いを吸収する単位。1dpは1/160インチ。
spドット密度やフォントサイズ設定の違いを吸収する単位。

dpは一見すると特殊ですが、ptやinの仲間ですね。どんな端末でも、160dpがディスプレイ上で1インチになるように調整されます。pxに換算すると、ドット密度に応じてスケールアップします。例えば10dpは、160dpiなら10px、240dpiなら15px(1.5倍)に換算されます。これで、見た目の大きさが同じになるということですね。

spは、システムフォントサイズに連動する単位のようです。Windowsプログラマなら「ダイアログ単位」を連想するでしょう。例えば、設定アプリで標準文字サイズを大きくすると、連動して1spの見た目も大きくなるんだと思います。

API

android.content.res.ResourcesクラスのgetDisplayMetrics()を呼ぶと、android.util.DisplayMetricsオブジェクトが手に入ります。このオブジェクトのdensityDpiフィールドがドット密度(dpi)です。またdensityフィールドは、dp値をpx値に変換するための倍率です。例えば、160dpiの端末では1、240dpiの端末なら1.5です。

android.view.ViewConfigurationクラスのget()を呼ぶと、ViewConfigurationオブジェクトが手に入ります。このオブジェクトからも、いろんなメトリクスを取得できます。例えばgetScaledTouchSlop()は、タッチした指がどれくらい移動するとスクロールと判断されるかをpx単位で返します。

ベスト・プラクティス

GoogleのDevGuideは、以下の4点を挙げています。

  • XMLの中では、wrap_contentとfill_parent、あるいはdpを使う(ただし文字サイズにはspを使う)
  • コードの中では、固定ピクセル値(hard coded pixcel values)を使わない
  • AbsoluteLayoutを使わない(API Level3でdeprecatedとなったそうです)
  • ドット密度ごとにdrawableを用意する

2点目は、例えば、フリック(Fling)判定の閾値にpx単位の固定値を使うなということでしょう。例えば40px以上動いたらフリックと判断する、とか。mdpiやhdpiならともかく、xhdpiの端末で40pxは約3mmしかないので…。定数はdp単位で設定し、前述のDisplayMetrics.densityを掛けて、動的にpxに換算するべきですね。耳が痛いです。

Last modified:2011/06/02 21:35:01
Keyword(s):
References:[Androidアプリ開発]
This page is frozen.