Androidアプリケーション技術者認定試験ベーシックの試験範囲の知識をまとめた(3)

# ユーザーインターフェース１

## アクティビティとビュー

- アクティビティ 端末に表示するアプリの一画面全体
- ビュー アクティビティの中にパーツとして配置される部品
- 画面レイアウト、ビューによって組み上げられたアクティビティ
- インテント アクティビティ間の遷移をする機能

すべてのアクティビティはActivityのサブクラスとして実装する。
UIを持たないサービスと呼ばれるアプリケーションの場合にはアクティビティは必要ない

アプリケーションから呼び出されるアクティビティはマニュフェストファイルにその定義を記述しておく必要がある。
(`<intent-filter>`タグを使用する)

### ウィンドウ

- ウィンドウ アクティビティが常に一つ持っている。描画のための領域。ウィンドウサイズ＝アクティビティサイズ
- ビュー、画面に配置できるパーツ
- ウィジェット ビューの中でも機能を限定して用意された標準的なパーツ（TextView,Button,etc...)

### ビューグループ

- ビューグループ ビューやウィジェット階層的に持つことが出来るオブジェクト。

アクティビティは単一のビューまたはルートのビューグループを持つことが出来る。
アクティビティにルートのビューまたはビューグループを設定するにはActivityクラスのsetContentViewメソッドを使用する

### 複数のアクティビティを利用する

一つのアプリケーションで複数のアクティビティを持つことが出来る。
追加した場合はマニフェストファイルに定義を追加する必要がある

例：

```XML
<activity android:name=".SubActivity" />
```

　あるアクティビティから別のアクティビティを呼び出すにはインテントを使う

例:

```Java
Intent intent = new Intent(this, SubActivity.class);
startActivity(intent);
```

### アクティビティのサブクラス

|クラス名|用途|
|---|---|
|ListActivity|リストを表示するアクティビティ|
|ExpandableListActivity|行を展開できるリストを表示するアクティビティ|
|PreferenceActivity|設定画面用のアクティビティ|

### ListActivityクラス

リストを表示するためのアクティビティ。リストに表示するデータをセットするにはAdapterクラスを利用する。
よく使われるのはArrayAdapterクラスである。

## レイアウト

- レイアウト ビューやウィジェットをパーツとして、縦や横に並べたりすることで作成したもの。XMLで定義するか、コードで実装する

XMLファイルで作成する場合は、Eclipseプラグイン（ADT）のGraphical Layout Editorツールが使用できる（今となっては古いけど試験ではこっちで出るか？）
使用することで直観的に配置できる。

作ったXMLファイルを指定するにはsetContentViewにリソースIDで指定する

例:

```Java
setContentView(R.layout.main);
```

ファイル内で指定しているビューにアクセスするにはidをつける必要がある

例:

```XML
<TextView android:id="@+id/text_sample"/>
```

プログラムからこのテキストビューにアクセスするには、findViewByIdメソッドを使用する

例:
TextView tv = (TextView)findViewById( R.id.text_sample );

コードで作成する場合はViewGroupクラスのオブジェクトをsetContentViewメソッドの引数に指定する。

例：

```Java
FrameLayout frame = new FrameLayout(this);
TextView text = new TextView(this);
text.setText("Hello World!");
frame.addSubView(text);
setContentView(frame);
```

## レイアウトクラス

- FrameLayoutクラス 子の起点がすべてウィンドウの左上になるレイアウト。単純に追加すると左上に重なって追加される
- LinearLayoutクラス 指定した方向(orientationプロパティ)に従って子ビューを一列に配置するレイアウト
- RelativeLayoutクラス 子ビューがお互いに相対的な位置関係を持って配置されるレイアウト。

相対関係の一覧

|||
|---|---|
|Layout above|指定したリソースの上|
|Layout align baseline/left/right/top|baseline/left/right/topを指定したリソースに合わせる|
|Layout align parent baseline/left/right/top|baseline/left/right/topを親のbaseline/left/right/topに合わせる|
|Layout below|指定したリソースの下|
|Layout to left/right of|指定したリソースの左／右|

- TableLayoutクラス テーブル形式の表を表示できるレイアウト。
- GridLayoutクラス グリッド形式（テーブルと比較して行列両方向の結合も可能となっている）Android4.0で追加されたレイアウト

## イベント

- イベント ユーザからの入力の通知

### アクティビティのイベント

- キーボードイベント onKeyDown, onKeyUpなど
- メニューボタンイベント／コンテキストメニューイベント onCreateOptionsMenuなど
- タッチイベント onTouchEventなど
- ウィンドウフォーカスイベント onWindowFocusChanged

### ビューのイベント

アクティビティに配置したビューにもイベントは通知される。ビューのイベントを拾うためには、適切な**イベントリスナー**オブジェクトを作成し、ビューに登録しておく。
イベントが発生すると登録したイベントリスナーで定義されているメソッドが**コールバック**として呼び出される
イベントリスナーはJavaのインターフェースとして定義されているため、イベントリスナーオブジェクトを作成するには、匿名インナークラスを利用するか、イベントリスナーインタフェースを実装する専用クラスを定義する必要がある。

#### onTouchイベントの実装手順

OnTouchListenerインタフェースを実装し、setOnTouchListenerメソッドで登録をする

引数eventからはgetActionメソッドで取得する

よく使うアクション

|||
|---|---|
|ACTION_DOWN|指がタッチされた瞬間|
|ACTION_MOVE|指が動いた|
|ACTION_UP|指が離された|

#### onKeyイベントの実装手順

OnKeyListenerインターフェースを実装し、setOnKeyListenerメソッドで登録する

キーコードの例

|||
|---|---|
|KEYCODE_MENU|メニューキー|
|KEYCODE_BACK|Backキー|
|KEYCODE_VOLUME_UP|ボリュームアップボタン|
|KEYCODE_VOLUMEN_DOWN|ボリュームダウンボタン|

引数eventから取得できる主な情報

|||
|---|---|
|getAction|ACTIONタイプを取得する|
|getDownTime|キーが押されている時間を取得する|
|getRepeatCount|キーのリピートカウントを取得する|

ACTIONタイプの一覧
f
|||
|---|---|
|ACTION_DOWN|キーが押された瞬間のイベント|
|ACTION_UP|キーが押して離した後のイベント|
|ACTION_MULTIPLE|複数のキーを同時押しした時のイベント|

#### onClickイベントの実装手順

OnClickListenerインターフェースを実装し、setOnClickListenerメソッドで登録をする

#### onLongClickイベントの実装手順

OnLongClickListenerインターフェースを実装し、setOnClickListenerメソッドで登録する

###イベントの発生フロー

onTouch, onClick, onLongClickイベントの順番

1. onTouch: Action_Down
1. (条件を満たした場合のみ) onLongClick
1. (指が動いたと見なされた場合のみ) onTouch: ACTION_MOVE
1. onTouch: ACTION_UP
1. onClick

onKeyイベントの順番

1. onKey: KEY_DOWN
1. onKey: KEY_UP

### イベント処理の伝播

ActivityクラスのonTouchEventメソッドなど、boolean型が指定されているメソッドでは、trueを返すことでそのイベントがその裏にあるビューまで伝播しない、falseを返すことで伝播するようになる。

### UIスレッドとイベント処理

Androidはシングルスレッドモデルである。UIスレッドはメインスレッドで動いている。
そのため重い処理はワーカスレッドで行う必要がある。
ワーカースレッドでUI操作を呼び出すとCalledFromWrongThreadExceptionが発生する。

#### AsyncTaskクラスを利用する

この問題はAsyncTaskクラスを利用することで、回避できる。onPreExecute, onPostExecute, onProgressはUIメソッドで動くため。

#### AsyncTaskクラス利用時の注意点

　Android1.5から導入されたクラスである。
　インスタンスの再利用はできない。再実行するたびにインスタンスを生成する必要がある。

#### Handlerクラスを使う

Threadクラスを使う場合はHandlerクラスのpostメソッドを利用できる。

## メニュー

　- オプションメニュー 端末のメニューボタンを押下した時に表示される（3.0以降ではアクションバーをタップしたときに表示される)
- コンテキストメニュー 項目を長押しした際に表示されるメニューをコンテキストメニューという

以下はAndroid2.3(APIレベル10)以前を対象としている。

### オプションメニュー

XMLで定義する方法とコードで定義する方法がある。

XMLで定義した場合、MenuInflaterクラスのinflateメソッドを使用して適用する

例：

```Java
@Override
public boolean onCreateOptionsMenu(Menu menu){
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.geme_menu, menu);
    return true;
}
```

コードで定義する場合、onCreateOptionsMenuメソッドをオーバーライドし、メニューを初期化する必要がある

例:

```Java
@Override
public boolean onCreateOptionsMenu(Menu menu){
    menu.add(0, NEW_GAME_ID, 0, "new_game");
    menu.add(0, HELP_ID, 0, "help");
    return true;
}
```

アプリケーションの状態によって、オプションメニューの内容を変える必要がある場合、onPrepareOptionsMenuメソッドをオーバーライドする。

オプションメニューのイベントを処理するにはActivityクラスのonOptionsItemSelectedメソッドをオーバーライドする。
引数に渡されているMenuItemオブジェクトが選択されたアイテムとなる。

### サブメニュー

メニューにはサブアイテムを登録できる。MenuオブジェクトにaddSubMenuメソッドで追加するかXMLで定義する
チェック可能なアイテムを作成するにはsetCheckableメソッドでtrueを渡すか、XMLで定義する（checkable="true")

相互排他的なラジオボタンを作る場合は、グループを作成し、その中にラジオボタンメニューを追加し、同じグループIDにしたうえで、
そのグループIDに対してSubMenuクラスのsetGroupCheckableメソッドを使ってチェック可能にする。

応答は、第一階層のメニューアイテムと同じメソッドで行う。

### コンテキストメニューの作り方

コンテキストメニューを表示したいビューを、ActivityクラスのregisterForContextMenuメソッドで登録する必要がある。
登録しておくと、長押しクリックした場合に、onCreateContextMenuが呼び出されるようになるのでそこで初期化をする。

コンテキストメニューもXMLでもコードでも定義できる。onCreateContextMenuメソッドをオーバーライドして作成する。
アイテムが選択された時の処理はonContextItemSelectedメソッドをオーバーライドする。