このページの本文へ

これで作れる! Androidのアプリケーション 第4回

Androidアプリを構成する「アクティビティ」を実際に作る

2010年07月22日 12時00分更新

文● 塩田紳二

  • この記事をはてなブックマークに追加
  • 本文印刷

テキストやオブジェクトのサイズを指定する

 同様にEditText01のTextに「defaultNAMEText」を、Button01のTextに「NameButtonLabel」を指定します。こうすると、レイアウトエディターの表示がずいぶんと変化します。ですが、これでは寄りすぎで、ラベルの文字もちょっと小さすぎます。そこでこれを修正しましょう。

Textプロパティは修正したものの、左側に全部寄った状態になっている

 まずは、テキストのサイズを修正します。フォントのサイズは、プロパティの「Text size」で指定します。このとき、数値には単位を付けます。付けることができる単位は、

dp:density-independent pixels
sp:Scaled Pixel
px:pixel
pt:ポイント(1/72インチ単位)
mm:ミリメートル
in:インチ

です。たとえば、14ミリメートルに指定したければ、「14mm」と指定します。

 「dp」は「dip」と表記することもでき、画面の表示密度(dpi。1インチあたりのドット数)から計算される値で、表示密度が違っても、同じような物理サイズを維持できます。後述するspと似ていますが、こちらは、フォント設定が加味されないため、おもにフォント以外のサイズ指定に使うもののようです。dpは、160dpiの画面(Midium Density)のときの1ドットのサイズを基準にしており、表示密度が変わると自動的に160dpiのときの1ドットのサイズに合わせるように変換してくれます。

 「sp」は、dp同様に画面の表示密度に依存する値ですが、実行時に標準の文字サイズを基準にして調整が行われます。また「sip」と表記することも可能です。ただ、現在のAndroidのドキュメントでは、基準となる文字サイズを「user's font size preference」と表現しているのですが、Androidのシステム設定には、こうした設定はなく、何が基準になっているのかが不明です。このspを計算する基準となるscaledDensityという値については、「This is the same as density, except that it may be adjusted in smaller increments at runtime based on a user preference for the font size.」という表記があり、実行時に何らかの調整が行われるようです。

 実際に試してみると、レイアウトエディターのレベルでは、dpでもspでも、数値が同じなら同じような表示になります。ただし、フォントの設定が関連するため、基本的には、フォントのサイズ指定に使うもののようです。

 「px」は、いわゆるドット単位の指定で、解像度や画面サイズに関係なく、必ず指定したドット数になります。主にビットマップ画像などを扱うときに使います。

 「pt」、「mm」、「in」は、物理的なサイズを維持する単位で、画面密度などから計算された値に最終的に変換されます。ptは、おもに欧文文字の指定に使われるサイズで1/72インチが1ポイントになります。こちらは、人間が理解できる数値での指定で、実寸表示や印刷物の表示など、物理的なサイズを重視する場合に使うべきでしょう。

 アプリケーションを作るとき、表示する文字のサイズは、spまたdpを使って指定するのが普通です。spについてはdpとの差がわからないのですが、実行時にフォントサイズの調整がなされていることを考えると文字サイズについてのみspを使うほうがいいかもしれません。

 なお、TextViewでTextSizeを何も指定しないときのデフォルト値についてはドキュメントのどこにも記述がないのですが、14spまたは14dpが使われているようです。

 さて、サイズ指定がわかったので、フォントサイズを指定しておきましょう。TextView01をアウトラインで選択して、プロパティで、「Text size」を探し17sp程度を指定します。これは、2番目にあるEditText01の枠サイズなどを考慮して少し大きくしておくためです。

プロパティでTextViewのText sizeを17spとする。これで左側の文字が大きく表示されるようになる

 さて、いまのレイアウトでは、左側に全部寄ってしまっていて右側が無駄に空いています。これを調整しましょう。まずLinerLayout01を選択します。すると、赤い枠が表示されます。

アウトラインでLinearLayoutを選択すると、現在のサイズが赤い枠で表示される。何も設定していないと、中身のビューを包むようなサイズとなる

 これが、現在のLinerLayoutのサイズです。中にある3つのビューの外側を包むような感じになっています。プロパティの「その他」にある「Layout width」を見ると「wrap_content」となっています。これは、中身(content)を包む横幅という意味の指定です。これをクリックして「fill_content」に切り替えてみます。すると赤い枠は左右全体に広がります。

Layout widthにfull_parentを指定すると、親のサイズ(この場合には画面の横幅)まで、横幅が広がる

 こうしたレイアウトでは、入力欄は大きいほうがいいので、EditText01を最大限に広げます。プロパティで「Layout weight」を選択して「1」を入れます。

TextEditのLayout weightに1を設定すると、幅が広がり、余白部分がなくなる

 すると、EditText01が右側に大きくなり、ボタンが右端に来ました。「Layout weight」は、LinerLayoutの範囲内で、ビューにサイズを割り当てるときの重みを指定するものです。デフォルト値は0ですが、ビューは中身のサイズ以下に縮められることはありません。このため、複数のビューがあるとき、それぞれの最小値を確保した残りをweightの値を元に分配することになります。基本的に0以外の同じweight値が指定してあれば、同じサイズになります。

 今回は、TextView01とButton01は、最小限のサイズとして、残りをEditText01に割り当てるために1を指定しました。このやり方は、複数のビューをLinerLayoutに配置するときの基本的なテクニックです。なお、割り当ては、LinerLayoutのOrientationの方向のみ有効です。

 LinerLayoutは、複数のビューを配置するときには、ビュー自身の大きさとweightでしか配置を制御できません。なので、OrientationにHorizontalが指定してあるLinerLayout01は、水平方向の制御だけが可能です。垂直方向のサイズを変更したい場合には、中のビューの高さを指定して大きくするか、最上位のLinerLayoutでの制御を使います。これは、LinerLayout01自身のLayout weightを設定することで可能です。たとえば、1を設定すると、LinerLayout01は、下側の残りすべてを含むようになります。

 最後に、定義されているオブジェクトのidをわかりやすいものに変えましょう。オブジェクトをレイアウトエディターにドロップした状態では、連番のついたidが使われますが、これだと、オブジェクトが増えたときにどれがどれだかわからなくなってしまいます。そこで以下のように各オブジェクトのプロパティで「id」を書き換えます。

アウトラインの表示 idに設定する値
LinearLayout @+id/MainVerticalLayout
TextView @+id/Message
LinearLayout01 @+id/InputAreaHLayout
TextView01 @+id/InputLabel
EditText01 @+id/InputText
Button01 @+id/SetButton

 ここまで、作業すると、main.xmlの内容は以下のリスト1のようになります。なお、xmlのタグ内のアトリビュートの順番が違っていることがあります。これはプロパティで設定した順に追加されていくので、タグ内での順番は違っていても問題ありません。また、リストは複数行に別れていますが、つながっていることもあります(このあたりの問題はXMLの基本的なことなので、わからないときにはXML関連の書籍を参照してください)。

リスト01 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:id="@+id/MainVerticalLayout">
  <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    android:id="@+id/Message"/>
    <LinearLayout android:layout_height="wrap_content"
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:id="@+id/InputAreaHLayout">
      <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/editNameLabel"
        android:textSize="17sp"
        android:id="@+id/InputLabel">
      </TextView>
      <EditText android:id="@+id/EditText01"
        android:layout_height="wrap_content"
        android:text="@string/defaultNAMEText"
        android:layout_width="wrap_content"
        android:layout_weight="1"
        android:id="@+id/InputText">
      </EditText>
      <Button android:id="@+id/Button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/NameButtonLabel"
        android:id="@+id/SetButton">
      </Button>
    </LinearLayout>
</LinearLayout>

 なお横向きへの対応や多国語対応に関しては、ある程度アプリケーションの目処がたったあとで作業するほうがいいでしょう。というのはレイアウト自体、プログラムの開発に応じて、いろいろと変化していくものなので、縦向きの画面関係が落ち着いてから、横向き画面や、多国語用の表示を考えほうが修正の手間がなく作業が簡単になるからです。

カテゴリートップへ

この連載の記事

注目ニュース

ASCII倶楽部

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン