Androidの画面(User Interface)の作り方

概要

Androidでは、Button(ボタン)、RadioButton(ラジオボタン)、チェックボックス(CheckButton)などの部品を、View(ビュー)やWidget(ウィジェット)と呼びます。
※ここからは、これらの部品を英語表記で、Viewと記載していきます。

そして、このViewを含めることができるViewGroupというものがあります。
androidでは、ViewGroupの中に、Viewを配置していく形をとります。

代表的なViewGroup

Layout名 内容
LinearLayout 要素を縦または横の一列に並べるレイアウト
RelativeLayout 相対的な位置を指定して部品を配置するレイアウト
TableLayout/TableRow TableLayout:格子上に配置レイアウトです。HTMLのTableタグの構成と似ています。TableRow:テーブルの行 HTMLのtrタグと似ています。
FrameLayout 1つのViewを配置するだけのレイアウトですが、複数のViewを重ね合わせることもできます。
AbsoluteLayout 表示位置を絶対座標で指定するレイアウト

 

代表的なView

View名 内容
TextView テキストを表示する
EditView 入力エリアを表示する
HTMLのテキストボックス(input type=”text”)に相当
Button ボタン
Checkbox チェックボックス
ImageView 画像を配置する
ImageButton 画像ボタン
RadioButton ラジオボタン
GridView データを格子状(又は方眼)で表示する(スクロールが出来る)
ListView データをリストで表示する(スクロールが出来る)
ProgressBar プログレスバー
AnalogClock / DigitalClock  アナログ時計 / デジタル時計
ZoomSlider  ズームスライダー

単位

Androidには様々な画面サイズ、画面密度(解像度)の端末が存在している為、
複数解像度の端末に対応するdp(dip)という最適な単位が用意されています。dp(dip) = density-independent pixelsの略です。
(密度非依存のピクセル)

dpは160dpi(dots per inch) の画面を基準とされています。160dpiの画面で、1dipは、1ピクセルと同じになります。
解像度に対する1dipが何pxになるのかついては、以下の方法で計算できます。
px = dp * (dpi / 160)
320dpiの画面の場合だと1dipは2pxで計算され、画面上に反映されることになります。
よって、dpで記載することにより、解像度が違う端末にも対応できます。
sp = scale-independent pixels
(スケール非依存のピクセル)
画面密度とユーザーのフォントサイズ設定の両方を加味する為、フォントサイズの指定で推奨されている。

画面作成

それでは、頻繁に使用されるレイアウトの1つである、LinearLayout(リニアレイアウト)を使用し説明して行きます。
LinearLayoutは、Viewを縦又は横に配置していくレイアウトです。
Viewは順番に上もしくは、左から順に並べることができます。

android-layout-linearLayout-011

LinearLayoutActivity.java

public class LinearLayoutActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_linearlayout);
    }

〜〜以下一部省略〜〜

}

上記のactivityのポイントは、レイアウトをセットするsetContentViewのみです。

activity_linearlayout.xml




    

    
        

        
        

    

    
        
        
        
    
    

    
        

上記の属性について、記載します。

属性 内容
orientation 縦横に配置する
vertical:縦に並べる / horizontal:横に並べる
layout_width 横幅
layout_height 縦幅
layout_weight レイアウトの比重
layout_gravity レイアウト自体の配置場所
gravity レイアウト内のViewの配置場所もしくは、View内のテキストなどの配置場所

この例は、まず、画面の大枠であるLinearLayoutに
android:orientation=”vertical”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
を定義していますが、これは、縦に並べて、widthとheightは、
画面一杯にViewを配置するように指定しています。

また、その中に、入れ子で、LinearLayoutが2つ配置されており、
それぞれ、横と縦のレイアウトにしています。

以上が、基本的なLinearLayoutのパターンになります。

つづいて、ListViewの説明になります。

リスト形式の画面を作成する

リスト形式の画面を作成するには、ListViewというViewを使用します。

listview_01

作成方法は、以下になります。

public class SampleListViewActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sample_list_view);

        String[] memoLists = new String[] {
                "memo1", "memo2", "memo3", "memo4"
                ,"memo5", "memo5", "memo6", "memo7"
        };

        ArrayAdapter adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_1, memoLists);


        ListView listView = (ListView)findViewById(R.id.ListView01);
        listView.setAdapter(adapter);

    }

上記には、2点のポイントがあります。

        ArrayAdapter adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_1, memoLists);

まず、Adapterを「android.R.layout.simple_list_item_1」とひも付けます。
「android.R.layout.simple_list_item_1」は、Androidにはじめから入っている
レイアウト(TextView)です。

※Adapterは、Viewとデータの橋渡しの役割を担っています。
※ArrayAdapterは、「配列」もしくは「リスト」のデータをTextViewにセットする役割を担っています。

        ListView listView = (ListView)findViewById(R.id.ListView01);
        listView.setAdapter(adapter);

ListViewに、上記で作成したadapterをセットし、表示させるという流れになります。

つづいて、レイアウトですが、以下のように、ListViewのViewを定義するのみです。




    


つづいて、ListViewのカスタマイズについて、解説しています。

独自レイアウトの作り方 ListViewのカスタマイズ

Screen-Shot-2014-08-29-at-1.29.13

上記のように、独自レイアウトを表示させるには、ListViewをカスタマイズします。

public class SimpleAdapterActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple_adapter);


        SimpleAdapter sa = new SimpleAdapter(this,
                getListData(),
                R.layout.activity_simple_adapter_row,
                new String[]{"content", "created"},
                new int[]{R.id.content, R.id.created});

        ListView listView = (ListView)findViewById(R.id.ListView01);
        listView.setAdapter(sa);

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.simple_adapter, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private List> getListData() {
        List> listData = new ArrayList>();

        listData.add(getMapData(new String[][] { { "content", "これはメモ01" }, { "created", "2014-09-13" } }));
        listData.add(getMapData(new String[][] { { "content", "これはメモ02" }, { "created", "2014-09-14" } }));
        listData.add(getMapData(new String[][] { { "content", "これはメモ03" }, { "created", "2014-09-15" } }));
        listData.add(getMapData(new String[][] { { "content", "これはメモ04" }, { "created", "2014-09-16" } }));
        listData.add(getMapData(new String[][] { { "content", "これはメモ05" }, { "created", "2014-09-17" } }));
        listData.add(getMapData(new String[][] { { "content", "これはメモ06" }, { "created", "2014-09-18" } }));
        listData.add(getMapData(new String[][] { { "content", "これはメモ07" }, { "created", "2014-09-19" } }));
        listData.add(getMapData(new String[][] { { "content", "これはメモ08" }, { "created", "2014-09-20" } }));
        listData.add(getMapData(new String[][] { { "content", "これはメモ09" }, { "created", "2014-09-21" } }));
        listData.add(getMapData(new String[][] { { "content", "これはメモ10" }, { "created", "2014-09-22" } }));

        return listData;
    }

    private Map getMapData(String[][] values) {

        Map map = new HashMap();
        for (int i = 0; i < values.length; i++) {
            map.put(values[i][0], values[i][1]);
        }

        return map;
    }

}

上記のポイントとして、SimpleAdapterクラスを使用してます。
このクラスは、レイアウト内にある複数のViewにセットできるAdapterです。

SimpleAdapter(Context context, List> data, int resource, String[] from, int[] to)
引数 内容
第1引数 Context
第2引数 キーをString型にしたMapのList
第3引数 レイアウトのリソースID
第4引数 第2引数で指定したMapのキーをString型の配列で指定する
第5引数 第3引数で指定したレイアウト内にあるViewのIDをint型の配列で指定する(並びは、第4引数で指定したキーと合わせる)

以下は、レイアウトのメインファイルになります。



    

つづいて、上記のListViewの中に配置するViewが定義されたレイアウトになります。





    

    

    


まとめ

Androidの画面作成は、はじめ理解するのが難しいかもしれません。ひとつひとつ理解してもらえればと思います。

ABOUTこの記事をかいた人

hundredappsの管理人であり、ソフトウェア開発者です。 開発したソフトウェアで、世の中の不便を1つでも改善できたらと思います。