2017年7月22日土曜日

Android開発初心者の壁レイアウト、そしてWeight

Androidアプリ開発を初めてしているほとんどの方はこう思うはずです。
Androidのレイアウトって難しい。
では何故こう感じるか、そしてレイアウトの考え方のお話をします。

まずAndroidはiPhoneと大きく違う所があります。
それは画面サイズです。iPhoneはAppleだけが製造しているためサイズも数種類しかありません(最近増えてますが...笑)
一方Androidは各メーカーが自由に設計、製造しているため画面サイズ、解像度がまちまちなんです。

そのため絶対座標でレイアウトを作ると小さい端末でははみ出て、大きい端末では余白が出来てしまいます。

この問題を解決するためにAndroidではWeight(重み)という概念を使います。簡単に言い換えるとです。

まず最初にlayout_widthとlayout_heightについて理解する必要があります。

layout_widthは横幅、layout_heightは縦幅です。

これらに代入出来る内容は同じで数種類あります。

match_parent 親のサイズに合わせる
wrap_content 自分を表示できる最小サイズ
fill_parent 親のサイズに合わせる
Xdp

この4つです。
fill_parentは過去の遺産なので忘れましょう。意味としてはmatch_parentと一緒です

Androidのレイアウトは親子関係があります。
画面幅が100、中にあるLinearLayoutの幅が50でその中のボタンをmatch_parentにした場合ボタンのサイズは50になります。
XdpはXに数字が入ります。上のバー(アクションバーって言います)は48dpといったように色々決まってます。ここの数字はあまり使わない...はずです。
というか必要最低限に抑えるようにすると良いです。



では本題であるWeightについてです。
まず、前提としてWeightを使うときのみLinearLayoutの向きに応じて幅を0dpにします。

horizontalまたは未指定の場合はlayout_width
verticalの場合はlayout_height

を0dpにします。
0dpにしない使い方もありますがここでは省略します。

あと、最近のAndroidStudioはConstraintLayoutというのが標準になってしまっているので
android.support.constraint.ConstraintLayout

LinearLayout 
に書き換えた上でapp:から始まる行を全て消しましょう。
これらはConstraintLayout専用のパラメータなので大丈夫です。
ついでにLinearLayoutの中に
android:orientation="vertical"
を追記しておきます。

条件

  • ルート(一番親)はLinearLayoutでvertical指定
  • その下にLinearLayoutを置いてhorizontal(水色に設定してあります)
  • 全てのボタンはwidthが0dp
  • ボタンの数字は設定しているWeightの数値

この図を見たら分かる事が色々あると思います。
1つだけ設置してweightを1にするとmatch-parentと同じ動きをします。
2つ設置して両方1にすると半々になります。同じ重さの物は同じサイズになります。3、4と増えていっても同じく同じサイズです。

Weightが1の物2つ = Weightが2の物1つ (上から5,6つ目の画像)

ちなみにWeightは100分率の考え方も出来ます。
80:20だったら両辺10で割って8と2にすれば画面幅80%と20%に別れます。(80と20でも大丈夫)

片方を85%,もう片方を15%にしたいならそれぞれその数字を入力すればOK。

最低限これだけが分かっていればAndroidのレイアウトはなんとでもなります。

つまるところ、そのViewのWeight/Viewが入ってるLinearLayoutの中のView達のWeightの総和の画面幅になるってことです。

豆知識として画面右と画面左(上下も可)に表示したい時はボタンをwrap_contentで2つ置いた後2つの隙間にSpaceを置いてSpaceだけWeightを1にすると左右にボタンが設置されます。
Weight未指定は0なので表示されない気がしますがwrap_contentが優先されるので、ボタンが最低限表示できる幅を保持したままSpaceが最大化されるためです。

とりあえずはこの知識があればAndroidのレイアウトは結構出来ます。
是非マスターしてみて下さい!
分からない事があれば質問していただければ分かる範囲で答えたいと思います。