【既存知識を】Androidの復習します！ - xml編 - 【自分なりに纏める①】


# 概略

相も変わらず初心者エンジニア続けています。
そんな私が一月Android開発に挑んだので
そのときの知識を備忘録と言うか、
まぁなんかそんな感じです。

開発環境はAndroidStudio1.0です。
xmlでビューを作っている時凄くレスポンスが早いので
勉強するなら断然eclipseよりAndroidStudioがお勧めです。

xmlを出来るだけコードで記述したのでその知識を共有します。

# Androidでxmlを使う際の基本知識

## 大きさの自動の指定

```xml
android:layout_width="match_parent"
android:layout_height="match_parent"
```

「wrap_content」・・・表示するものに合わせてビューサイズを自動で合わせる
「fill_parent」 ・・・画面いっぱいまで(API9以降)
「match_parent」・・・画面いっぱいまで(API8以下)

## dpについて

```xml
android:layout_width="20dp"
android:layout_height="50dp"
```
のように大きさを指定することがあります。

制作するアプリを縦で利用すると考えた際に
スマートフォンサイズでは320dp
タブレットサイズで600dpを最低ラインと想定してレイアウトを組めば
殆どの場合なんとか綺麗に見せることが出来るはずです。

しかし、Androidは機種が多くあり、画面解像度もバラバラです。
これでいいの？
と思いの方は下記Qiita記事がとても良記事で凄く参考になります。

[いまさら聞けないdp入門](http://qiita.com/nein37/items/0a92556a80c6c14503b2)

dpがある世界がやってきたおかげで、Androidの世界にも平穏が訪れました。

##idの指定

htmlを触ったことある人はわかると思いますが
それぞれのタグにユニークなidを設定することで
Activity等からアクセスしやすくなります。
ボタン等には
イベントの分岐などで使うのでなるべく分かりやすい
idを付けましょう。


# Layout（LinearLayout、FrameLayout）

今回よく使ったのは
リニアレイアウト(LinearLayout)
フレームレイアウト（FrameLayout）
の２つです。おそらくですが、Android開発においてこの２つの特性をよく理解すれば
割と何でも作れるようになったも同然です。（多分）

## LinearLayout

上から順、右から順にレイアウトを並べていくのに利用します。
htmlでいうdivタグのようなイメージだと理解して頂ければ大丈夫です。

### 普段使い

よくある使い方としては下記の様な感じになります。

```xml
<LinearLayout
    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" >

	<!-- 中身 -->
	
</LinearLayout>
```

> android:orientation="vertical"

このパラメータは縦に並べていく。というものです。

> android:orientation="horizontal"

としてあげると、横並びになります。defultでhorizontalなので、横並びの時はわざわざ記述する必要は有りませんが、明示してあげると引き継ぎの時喜ばれるはずです。

>xmlns:tools="http://schemas.android.com/tools"
>tools:context=".MainActivity"

この2つは該当Activityのテーマを読み込み、グラフィカルレイアウトに反映させることが出来ます。
例えば、アプリケーション全体に「Theme.AppCompat.Light.DarkActionBar」が適応されてるけど、MainActivityだけは「Theme.AppCompat.Light」にしたい。と言う時に利用できます。

[Android 「xmlns:tools」「tools:context」ってなんだろう？【Android TIPS】](http://www.sakc.jp/blog/archives/29829)

こちらのサイトが参考になりますのでご参考までに。

### LinearLayout応用

どうにかして50% 50%でレイアウトを組めないだろうか。
と思う時が絶対にあると思います。その時は

```xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="50"
        />

    <TextView android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="50"
        />
</LinearLayout>
```

こんな感じで記述しましょう。

>android:layout_weight="50"

同じLinearLayout内にいるView同士の大きさを比率で指定することが出来ます。
またレイアウトが縦並び

>android:orientation="vertical"

となっている時には

>android:layout_height="0dp"

とViewの高さを0dpとしておきます。
何故ならばweightの設定で高さを取得してしまい、仮にheight="30dp"となっていると

LinearLayoutの50%分の高さ + 30dp

となってしまいます。最低限高さを30dp確保する等意図して行っていれば問題無いですが、ややこしいですのでやる際には注意しましょう。またandroid:layout_weight="50"と記述していますが、50%だから50としているわけでは有りません。例えば

```xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="2"
        />

    <TextView android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="3"
        />

    <TextView android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"
        />

    <TextView android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="4"
        />
</LinearLayout>
```

という感じに記述すると
上から順に20% 30% 10% 40%という風に高さを指定できます。
設定しているのは比率なのですね。


## FrameLayout

>「FrameLayoutとは、パーツをひとつだけ配置して使用するレイアウトです。」

と紹介されているのを見かけました。
実際にはパーツを複数置くことが出来ますが、
そのパーツは重なって表示されます。
僕が思うに、複数のパーツを重ねて、一つのまとまったパーツとして表示させるのがFrameLayoutと思います。

###例

```
<FrameLayout 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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
        <TextView android:text="hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView android:text="hello_world" android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
        <TextView android:text="hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:text="hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

</FrameLayout>
```

実行して頂けると中身がそれとなくわかると思うのですが、
LinearLayoutが二枚重なって表示されているため、
一つ目の「hello_world」が重複して表示されている状態になると思います。

## RelativeLayout（相対レイアウト）

今回僕はRelativeLayoutを使うことはなかったのですが紹介だけ。

とある属性さえ指定しなければ
扱いはどことなくFrameLayoutに近いです。
上の例ではFrameLayoutをRelativeLayoutに書き換えるだけでも普通に実行できると思います。

そのとある属性というのが

```xml
android:layout_alignParent〇〇 ="true"
```

というものです。此方を指定することで、右隅とか、左隅、等を指定できます。
また、

```
android:layout_to〇〇Of="@id/〇〇"
```

と、viewのidを指定することで
そのviewのいちから見た相対レイアウトでViewを指定することが出来ます。

[相対レイアウト (RelativeLayout)](http://androidguide.nomaki.jp/html/layout/relative/relativeMain.html)

このサイト様が参考にしました。詳細は此方をどうぞ。


# Viewパーツ

それぞれ見る部分に当たります。
LinearLayoutとかの中身に入れていくことで人目に触れるようになります。
ここでは設定できる属性とか、今回僕が使った時の利用法等を少しご紹介できればと思います。

この記事が理解の一助となると思いますので合わせてご覧ください。

[Android再入門 - はじめてのView](http://qiita.com/gabu/items/f9b4389ae0c03f525f04)

パーツMenu
- View & ViewGroup
- TextView
- ListView
- ImageView
- ImageButton

## View & ViewGroup

ViewGroup自体は
Viewの中にViewを置くという概念があるようですが、
そこまで複雑なレイアウトを組むことは現状稀です。

ですので、多くの場合はレイアウトの中にレイアウトを作り、
そのレイアウトのなかにビューパーツを組み込むレベルで済んでしまうと思います。

なので僕のこいつの使い方は

```xml
<View
    android:id="@+id/tabUnder"
    android:layout_width="fill_parent"
    android:layout_height="4dp"
    android:layout_gravity="bottom"
    android:background="#ff0000"/>
```

android:layout_gravityで下部に配置し、
高さを小さく設定することで
とあるビューのアンダーバーとして利用しました。

もしくはLinearLayoutでのweight設定では空白部分とするのに用いたり、
意外と汎用性は有ります。

## TextView

シンプルなテキストビューですね。
htmlで言うpタグみたいなやつです。

先程からちらちら使っていますが

```
<TextView android:text="hello_world"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content" />
```

こんな感じでテキスト「hello_world」を最低限幅で表示する。のようになっています。

ちょっと発展して利用するならば

```
<TextView
    android:id="@+id/title"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="20"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_marginTop="10dp"
    android:textSize="18sp"
    android:gravity="center"
    android:text=""
    
    android:maxLines="3"
    android:ellipsize="end"
    android:scrollHorizontally="true"
/>
```

こんな感じでしょうか。

>   android:maxLines="3"
    android:ellipsize="end"
    android:scrollHorizontally="true"

これは最大でも3行までの表示にして
文字列が3行で収まらないなら末尾を切り「...」に置換する
というものです。

また

> android:layout_marginLeft

と記述することでマージンを空けることが出来ます。同じくpaddingも設定できます。
若干htmlと仕様が異なりますので、色々試して見て下さい。

##ListView

こいつが意外と厄介な存在でした。

まぁ、使い方は簡単なのですが....

[ListViewの簡単な使い方](http://blog.h13i32maru.jp/entry/20110403/1301830422)
超シンプルに書くと上記記事のような感じになります。

僕が困ったポイントを紹介するので、参考にして頂けたらと思います。
ちなみに、僕はListFragmentを利用してやりましたので、
応用できなかったら御免なさい。

###Adapterって何？

ListViewを使うと必ずセットで利用することになるのがAdapterです。

初め、僕は **ListViewが** 最初から定型的なテンプレートを持っており、
アダプターはそのテンプレートにデータを受け渡しする物。
だと思っており、ListView側にレイアウトを変更する記述がいるのかなと思っていましたが、

ListViewに表示するレイアウトを決めているのはAdapterのようです。
というか、ListViewは受け皿みたいなもので、Adapterが表示関係の物を全て受け持っているようです。

ですので、上の記事さんから引用させていただくと

>アイコンや凝ったレイアウトを使いたい場合は各行のレイアウトとArrayAdapterを自作する必要があります。

ということですね。
自作に関しては
[techbooster リストビューをカスタマイズする](http://techbooster.org/android/ui/1282/)の記事が参考になります。

###一番上だけセルが大きいListViewを作ろうとしたら。

[techbooster リストビューをカスタマイズする](http://techbooster.org/android/ui/1282/)様の記事をご覧になった方。

```
// convertViewは使い回しされている可能性があるのでnullの時だけ新しく作る
 if (null == convertView) {
 convertView = layoutInflater_.inflate(R.layout.custom_layout, null);
 }
```

この部分に注目して頂きたいです。
convertViewというやつがおりますね。

getViewメソッドの引数にもなっているのですが...
本来であればListViewの再利用を促してくれる、メモリに優しい良い奴なのです。

[ListViewのデータのbindはこうする2014](http://rejasupotaro.github.io/2014/02/06/34.html)

此方の記事をご覧頂ければその凄さというか、素晴らしさが理解できると思います。



個別にレイアウトを変えようと思うと事情が変わってきます。

convertViewは表示域からいなくなったListViewのセルのレイアウトを拾ってきています。
そのため、convertViewに新しくデータを入れるだけだと、
当たり前ですがレイアウトが変わりません。

しかもconvertView自体何番目のセルなのか判断する術が有りません（多分）

一番上のセルだけにAというレイアウトで、他のセルはBというレイアウトにしたい！
という時でも、
一番上のセルがスクロールされてフェードアウトすると、AというレイアウトがconvertViewに拾われてしまいます。

![listview_recycler.jpg](https://qiita-image-store.s3.amazonaws.com/0/42310/ba856387-1e6a-4caf-5527-fc7f1ef7f2a3.jpeg "listview_recycler.jpg")

>[HowTo: ListView, Adapter, getView and different list items’ layouts in one ListView](http://android.amberfog.com/?p=296)より画像を引用。

何番目かのセルでconvertViewを利用してセルを作ってしまうと、そのセルはAというレイアウトになってしまう。ということです。


##ImageView

画像を表示するためのViewです。

例えば、横いっぱいで、縦にある程度の高さの画像を表示するなら

```
    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="158dp"
        android:id="@+id/imageView"
        android:src="@drawable/noimages"
        />
```

こんな感じになります。
srcは画像の参照先ですよね。htmlと同じです。
@drawableですが、ディレクトリにdrawableというのがあると思います。
この中に例えばnoimages.pngという画像データを入れておけば、
それを参照して表示することが出来ます。

ですが、これをただ表示するだけでは変な表示になってしまいます。
例えば正方形の画像だと、分かりやすいですが
縦いっぱいに表示して、横いっぱいに届かない大きさの場合、画像の比率が優先されるため、表示粋いっぱいに画像が表示されません。

そんな時は **android:scaleType** という属性を設定してあげることで様々な画像の表示方法を選ぶことが出来ます。

そんなアレヤコレヤを纏めてくださっているのが
[[Android] ImageViewをScreenにフィットさせる](https://akira-watson.com/android/imageview_scaletype.html)
此方のサイト様の記事です。

是非確認してみてください。



##ImageButton

imegeViewのボタンにしたやつです。

一般的な使い方は...こんな感じでしょうか？

```
        <ImageButton
            android:id="@+id/buttom"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@drawable/off"
            android:background="@null"
            android:clickable="true"
            android:onClick="Button"
            />
```

> android:clickable

クリック可能かどうかを記したもの。
ImageButtonなんで初期値がtrueなんでわざわざ書かなくても良いです。

> android:onClick="Button"

もしクリックされた際に動くメソッドを指定できます。
Buttomメソッドが動くってことですね。

Androidはちょっとめんどくさいことに
タップされたものは全部一度onClickに処理が流てしまいます。
なので、xmlで最初から処理をするメソッドを指定できるとすごい楽です。

この上記2つのパラメータはImageButton以外にも利用できて、ImageView,TextViewをクリックした時のイベントを取得したい時とかに設定してみてください。


#以上です。

もし質問があれば是非コメントへ書いて頂けると、僕も勉強になります！
宜しくお願いしますm(_ _)m