Androidアプリ入門 No.04 サイズ
ウィジェット共通
サイズ
サイズは以下の種類がある。
種類 | 説明 |
---|---|
sp | スクリーン上の相対的な画素サイズに合わせて調整されるピクセル。画面の解像度だけでなくユーザーが設定したフォントサイズにも依存する。 |
pt | デバイスに依存したポイントサイズ。 |
dpもしくはdip | デバイスから独立したポイント。1インチに160ピクセルあると仮定した際に、そこに表示するピクセル数を指定する。つまり、1インチに240ピクセルあるモニタに表示する際に100と指定すると、240/160=1.5となるため、物理モニタには150ピクセル表示される。 |
px | 物理的なピクセルサイズ。 |
レイアウトにはdip、文字にはspを使うのがデバイス依存しなくてよい。以下の例で確認できる。画面の画素数に対して相対的なサイズになるため、基本的には端末が違っても同様のレイアウトになる可能性が高い。
たとえば、以下のように定義する。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00f " > <TextView android:layout_width="100dip" android:layout_height="wrap_content" android:text="こんにちはメインアクティビティ" android:textColor="#000" android:background="#80ffffff" android:textStyle="italic" android:textSize="16sp" /> </LinearLayout>
以下の画面で最初の画面が400×240(WQVGA)のサイズで表示した画面、次の画像が800×480(WVGA)のサイズで表示した画面である。画面の比率に応じてサイズが変わっているのがわかる。
ここでもう少し深くdp、spについてみる。まずdpについて確認する。dpは1インチに160ピクセルの画素がある場合のピクセル数を指定することになる。dpに対しての実際のピクセルの計算式は以下のようになる。
表示のピクセル数 = 端末のdensity ÷ 160 × 指定のdp
ここでエミュレータの詳細画面を見てみる。
そうするとhw.lcd.densityという項目があり240という数字になっている。これがこのエミュレータの1インチ当たりのピクセル数となる。
つまり、このエミュレータで120dpを想定すると先の計算式に当てはめると、ピクセル数は180pxとなる。実際にそのように動作しているか、main.xmlを以下のように定義して確かめる。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" > <LinearLayout android:orientation="vertical" android:layout_width="120dp" android:layout_height="50dp" android:background="#ff0000"> </LinearLayout> <LinearLayout android:orientation="vertical" android:layout_width="180px" android:layout_height="50dp" android:background="#00ff00"> </LinearLayout> </LinearLayout>
次に、spとptの関係を確認する。spとptは直接的には関係しない。以下実例で説明する。まず、MainActivity。
package sample.at; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView text1 = (TextView) findViewById(R.id.text1); text1.setText("scaled= " + getBaseContext().getResources().getDisplayMetrics().scaledDensity); TextView text2 = (TextView) findViewById(R.id.text2); text2.setTextSize(30.0f); } }
次に、main.xml。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/blue" > <TextView android:id="@+id/text1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="こんにちはABCabc123" android:textColor="#000" android:background="#80ffffff" android:textSize="30sp" /> <TextView android:id="@+id/text2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="こんにちはABCabc123" android:textColor="#000" android:background="#80ffffff" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="こんにちはABCabc123" android:textColor="#000" android:background="#80ffffff" android:textSize="30sp" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="こんにちはABCabc123" android:textColor="#000" android:background="#80ffffff" android:textSize="20sp" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="こんにちはABCabc123" android:textColor="#000" android:background="#80ffffff" android:textSize="13pt" /> </LinearLayout>
次に、MainActivityでscaledDensityを明示して変更する。
package sample.at; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); getBaseContext().getResources().getDisplayMetrics().scaledDensity = 1.0f; TextView text1 = (TextView) findViewById(R.id.text1); text1.setText("scaled= " + getBaseContext().getResources().getDisplayMetrics().scaledDensity); TextView text2 = (TextView) findViewById(R.id.text2); text2.setTextSize(30.0f); } }
実行結果。text2が小さい文字になっていることが分かる。つまりptやspはscaledDensityには依存しないが、プログラムから明示したsetTextSizeはscaledDensityに依存していることが分かる。
結局spが何者であるかはよく分からない。誰か教えてください。