マス目、格子状に区切ったレイアウトをしたい場合にTableLayoutを使うと簡単にできるようです。どういうわけかうまく行かないことが度々あるので整理してみたいと思います。
2021.2.1
TableLayout
マス目としてはGridViewを使うという選択肢もありますが、要素が固定で簡単に作りたい場合はTableLayoutが合っているかもしれません。
作成の基として TableLayoutタブでくくり、その中に入れたい行数分のTableRowタグを作り、そこにボタン、画像などを入れます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<TableLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <!-- 1行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> ... </TableRow> <!-- 2行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> ... </TableRow> <!-- 3行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> ... </TableRow> </TableLayout> |
実際に作ってみると分かりやすいでしょう。
Buttonを並べる
ボタンを3x3で9個マス目状に並べてみます。
(MainActivity.javaではデフォルトのままでこのactivity_main.xmlを呼んでいるだけなので割愛します。)
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <!-- 1行目 --> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button_11" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button11"/> <Button android:id="@+id/button_12" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button12"/> <Button android:id="@+id/button_13" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button13"/> </TableRow> <!-- 2行目 --> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button_21" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button21"/> <Button android:id="@+id/button_22" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button22"/> <Button android:id="@+id/button_23" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button23"/> </TableRow> <!-- 3行目 --> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button_31" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button31"/> <Button android:id="@+id/button_32" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button32"/> <Button android:id="@+id/button_33" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button33"/> </TableRow> </TableLayout> |
strings.xml
1 2 3 4 5 6 7 8 9 10 11 12 |
<resources> <string name="app_name">TestTableLayout</string> <string name="button11">(1,1)</string> <string name="button12">(1,2)</string> <string name="button13">(1,3)</string> <string name="button21">(2,1)</string> <string name="button22">(2,2)</string> <string name="button23">(2,3)</string> <string name="button31">(3,1)</string> <string name="button32">(3,2)</string> <string name="button33">(3,3)</string> </resources> |
このようになりました。
これで目的が達成していればこれでいいのですが、いやいや、横幅いっぱいにした方が綺麗だろうというご意見が出てくるわけです。
横幅いっぱいにレイアウト
横幅いっぱいにするのですが、当然均一にしてほしいという要望があるはずなので、ここはweightを使います。
1 2 |
android:layout_width="0dp" android:layout_weight="1" |
これを使ってそれぞれ修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <!-- 1行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/button_11" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/button11"/> <Button android:id="@+id/button_12" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/button12"/> <Button android:id="@+id/button_13" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/button13"/> </TableRow> <!-- 2行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/button_21" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/button21"/> <Button android:id="@+id/button_22" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/button22"/> <Button android:id="@+id/button_23" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/button23"/> </TableRow> <!-- 3行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/button_31" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/button31"/> <Button android:id="@+id/button_32" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/button32"/> <Button android:id="@+id/button_33" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/button33"/> </TableRow> </TableLayout> |
strings.xml
1 2 3 4 5 6 7 8 9 10 11 12 |
<resources> <string name="app_name">YourAppName</string> <string name="button11">(1,1)</string> <string name="button12">(1,2)</string> <string name="button13">(1,3)</string> <string name="button21">(2,1)</string> <string name="button22">(2,2)</string> <string name="button23">(2,3)</string> <string name="button31">(3,1)</string> <string name="button32">(3,2)</string> <string name="button33">(3,3)</string> </resources> |
うまくいきました。ところでこのようなレイアウトにする場合は画像を使うケースが多いのではないでしょうか。
画像を並べる
画像の場合はボタンと違って高さがあります。またその画像の縦横の大きさも関係します。
例えば256×256 pxelの同じ画像を並べようとするとこのようになります。
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <!-- 1行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> </TableRow> <!-- 2行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> </TableRow> <!-- 3行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> </TableRow> </TableLayout> |
strings.xml
1 2 3 4 |
<resources> <string name="app_name">YourAppName</string> <string name="description">Miki</string> </resources> |
横幅がオーバーしているので、均等になるように以下のweightを設定してみます。
1 2 |
android:layout_width="0dp" android:layout_weight="1" |
横幅は均等になりましたが、高さがうまくいっていません。
高さを均一にする
weightを縦方向に設定する方法で試してみます。今回weightをかけるところはTableRowになります。
1 2 3 4 |
<TableRow android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > |
これでコードを記述すると
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <!-- 1行目 --> <TableRow android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> </TableRow> <!-- 2行目 --> <TableRow android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> </TableRow> <!-- 3行目 --> <TableRow android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_256" android:contentDescription="@string/description"/> </TableRow> </TableLayout> |
strings.xml
1 2 3 4 |
<resources> <string name="app_name">YourAppName</string> <string name="description">Miki</string> </resources> |
高さも均一になりました。ただ高さが均一ですがこの場合、縦方向のスペースが空きすぎではと思います。
縦方向に詰める
ここまでくるとあまり良い方法が見つかりません、android:shrinkColumnsが効くかと思ったのですが…
安直ですが縦をdpで指定することしか思いつかないですね。ここが結局TableLayoutの限界のような気がします。
1 2 3 4 5 |
<ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="150dp" android:src="@drawable/img_256"/> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <!-- 1行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="150dp" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="150dp" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="150dp" android:src="@drawable/img_256" android:contentDescription="@string/description"/> </TableRow> <!-- 2行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="150dp" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="150dp" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="150dp" android:src="@drawable/img_256" android:contentDescription="@string/description"/> </TableRow> <!-- 3行目 --> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="150dp" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="150dp" android:src="@drawable/img_256" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="150dp" android:src="@drawable/img_256" android:contentDescription="@string/description"/> </TableRow> </TableLayout> |
strings.xml
1 2 3 4 |
<resources> <string name="app_name">YourAppName</string> <string name="description">Miki</string> </resources> |
最初の1列目のみの設定であとは追従してくれました。
小さい画像
実は画像サイズをもっと小さくすればこの辺りはうまくできるようです。
256×256から128×128のサイズに変更します。
もっとも簡単なコードでやってみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <!-- 1行目 --> <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_128" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_128" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_128" android:contentDescription="@string/description"/> </TableRow> <!-- 2行目 --> <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_128" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_128" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_128" android:contentDescription="@string/description"/> </TableRow> <!-- 3行目 --> <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_128" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_128" android:contentDescription="@string/description"/> <ImageView android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:src="@drawable/img_128" android:contentDescription="@string/description"/> </TableRow> </TableLayout> |
strings.xml
1 2 3 4 |
<resources> <string name="app_name">YourAppName</string> <string name="description">Miki</string> </resources> |
なんだか遠回りしたような気がしますが、レイアウトで自動的に拡大縮小してくれるのに期待しすぎてはいけないのでしょう。Out of Memoryにハマる危険性もありますし、これ以上の細かい設定はコーディングでTableLayoutなど使わずに計算して記述するほうが結局は早いのでしょうね