2011年10月4日火曜日

Chapter10: 単位について(dp, sp, px)

今回はAndroidの単位についてです。
Webデザイナーの方は普段は単位はpxのみ気にしておけば、ほぼ大丈夫かと思いますが(印刷物はdpi気にしますが)Androidの場合は違います。

理由は、端末によって解像度が違うためですね。
日本のAndroidで主流の解像度は以下の通りです。
  • 800x480(hdpi)
  • 854x480(hdpi)
  • 960x640(hdpi)
また、主流ではないですが、以下の解像度の端末もあります。
  • 480x320(mdpi)
  • 320x240(ldpi)
これだけあると、それぞれ専用のレイアウトを準備しないといけなさそうです。実際、準備する場合もあります。マルチスクリーンに関しては、別の機会に書こうと思います。今はシンプルに単位だけに注目します。

Android Developersのサイトに、Supporting Multiple Screensという項目があります。まさに別の機会にとさっき書いたばかりの項目ですが、そこに、単位についても書いてあります。

  • dp(dip: density-independent pixel)
  • sp(scaled pixel)
  • px(pixel)
dp(dip)は、解像度に依存しないpixelです。
解像度に合わせて自動的にpixel変換が行われます。

hdpiの端末は、240dpiです。

240 / 160(基準値) = 1.5px = 1dp

という計算になります。画面上で1.5pxは描けませんが、1dpは描けます。

mdpiの端末は、160dpiです。

160 / 160(基準値) = 1px = 1dp

という計算になります。

これを、px換算の解像度に当てはめると、

800x480(hdpi)の端末だと、533dp x 320dpでした。
480x320(mdpi)の端末だと、480dp x 320dpでした。

なんとdp上だと、横の長さが320dpで一致しましたね。

以下、800x480(hdpi)の端末です。
次は480x320(mdip)の端末(エミュレータ)です。

16dpと書いている文字の大きさはどちらも同じですが、16pxと書いている文字の大きさは明らかに違います。特に、480x320の画面では、16dpも16pxも同じ大きさです。しかし、800x480の画面では違います。16dpの文字の大きさはpxに換算すると16dp x 1.5 = 24px の文字になるからです。

しかし、画面の幅自体は、どちらの端末も320dpです。画面の縦横比が違うので、ちょっと見づらいかもしれませんが、端末自体の大きさ(解像度でなく)が同じならば、文字のサイズは同じはずです。

dpを使えば、画面の解像度を意識する回数が減ります。dpを使っておけば、新しい解像度の端末が出ても、なんとなくちゃんと表示されて動いてくれるということも期待できます(モヤッとした言い回しですが)。

spという単位もありますが、spは文字の解像度設定に倣うという単位なので、基本的にレイアウトにではなく、フォントサイズ指定に使います。フォントサイズ指定ではdpではなくspを使いましょう。

コードレビュー

ではレイアウトのコードを見てみましょう。 Sample02プロジェクトの/res/layout/chapter10.xmlを開いてください。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <!-- 
        dp(dip)は、解像度に合わせてpxが変化する単位です。
        端末の解像度(dpi)に応じて、大きさが変化します。
        基本的にdp(dip)を使ってレイアウトを定義していきます。
        sp(scaled pixels)は主にフォント用の単位です。
        pxで定義する機会は、ほとんどないと言えますが意識する必要はあります。
     -->
    <!-- 普通はtextSizeにはdpは使いませんが、サンプルとして使ってます -->
    <TextView
        android:text="@string/chapter10_dp"
        android:textSize="16dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <!-- 普通はtextSizeにはspを使うのでこっちのが正解 -->
    <TextView
        android:text="@string/chapter10_sp"
        android:textSize="16sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <!-- 敢えてpxで指定してみた例。160dpi端末と240dpi端末で比較するといいです -->
    <TextView
        android:text="@string/chapter10_px"
        android:textSize="16px"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:text="@string/chapter10_description"
        android:textSize="16sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>
textSizeに、各単位(16dp, 16sp, 16px)を指定しています。 解像度の違う端末で見てみると違いがわかりやすいです。なかなか準備できないので、エミュレータで比較してみるのがよいでしょう。

0 件のコメント:

コメントを投稿