2014年11月11日火曜日

Android ActionBarとインタラクション

ActionBarとインタラクション制御


●ActionBarの基本


ActionBar:アプリにある複数の画面で恒久的に表示される、主にナビゲーションと適切なアクションの提示のために利用される重要なUIコンポーネント。

●4つのコンポーネント

□AppIcon

アプリのアイコン。ホームに戻る、階層を1つ戻るなどの役割を持たせることも可能。


□ViewControl

異なるViewに様々なデータを表示するような場合に、ユーザがすばやくViewを切り替えるためのもの。


□ActionItem Buttons(Action Buttons)

配置されるボタン類は、アプリやその画面のなかで最も重要なアクションを促す。シンプルな抽象化されたアイコンで表現することが多い。個数が多い場合は分割して、画面下部に表示させることも可能。


□Action Overflow

画面の大きさの影響で収まらなかったり、意図的にAction Overflowに入る様に設定したActionButtonsがここにまとめられる。
優先度が低い位置づけ。


●重要な要素1 NavigationMode

ActionBarの3つのナビゲーションモード。1つのActivityでは、3つのうちのいずれかを選択する。

□Standard Navigation

デフォルトのナビゲーションモード

□ListNavigation

ドロップダウンのリストから項目を1つ選択するタイプ。右下隅に▲が表示される。

ex)

getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

□TabNavigation

複数のタブから1つを選択してコンテンツを切り替えるタイプのナビゲーションモード。

タブの位置は画面の大きさによって決定される。

・横幅の狭い画面:アクションバーの直下
・横幅の広い画面:タイトル部分の右端に統合
→ 画面の縦横切り替えでもアクションバーのレイアウトが入れ替わる。

ex)

getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);


●重要な要素2 ActionItem


OptionMenu(メニューキーを押して表示するメニュー)の代替で、アクションバーに含められるメニュー。

□android:showAsAction:アクションバーへの出し方を決定する属性


・always:常に表示します。もっとも重要度が高い。
・ifRoom:ほかのActionBarのコンポーネントが占める領域を見て、空があれば表示する。
・never:常にActionBar上に表示せず、その他(右端の3つの点)のメニューの中にまとめられる。もっとも重要度が低い。

always、ifRoom、neverのいずれか1つを選択

・withText:横幅の広い画面において、アイコンだけでなく、文言も一緒に表示するオプション。

端末の画面サイズに応じて、ActionBarが自動でAction Itemの表示をハンドリングする。


・タブレット型のような大きなディスプレイでは、アイコンとラベルを同時に表示。
・モバイル向けの端末では、横幅によってアイコンのみの場合と、ラベルとアイコンの同時表示がある。
・横画面が480dp以上ない場合、常にどちらかだけの表示。


●重要な要素3 App Icon Navigation


標準でアクションバーの左端に表示されるアプリのアイコンを、ナビゲーションのためのUIとして機能させる。

Androidの流儀としての使い方として、下記の2つの役割が想定されている。

・ホームボタンの役割
・階層構造を上に戻る役割(左向きの矢印が一緒に表示される。)

●重要な要素4 Split ActionBar


ActionItemを画面上部のActionBarから切り離し、画面下部に1列に表示するモード。

ex) <activity>の属性して以下を設定
android:uiOptionsにsplitActionBarWhenNarrow



●ActionBarSherlock

Android2.x でも ActionBarの導入を行うときに使用する。


●ActionBarの見た目を変える


StyleResourceとして、Drawablを利用してカスタマイズ可能。

***

●インタラクション制御

□ActivityやFragmentのコールバックについて


扱うメニューによって、コールバックメソッドが異なる。

□OptionsMenu

・onPrepareOptionsMenu:表示前に、メニュー要素の状態を管理するために呼び出す
・onCreateOptionsMenu:構成を初期化するため、ActivityやFragmentのライフサイクルの中で1度だけ呼ば荒れう
・onOptionsItemSelected:OptionMenuの選択状況を見て、適切なアクションを起こすために呼び出される

ex)

public class MainActivity extends Activity {
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // ここで、状態に応じてメニューの有効・無効を切り替えたりなどの処理をする
        return super.onPrepareOptionsMenu(menu);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // ここで、この Activity で利用するメニューのリソースを読み込む
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // 選択されたメニューに対応するイベント処理をここで実行する
        return super.onOptionsItemSelected(item);
    }
}

□ContextMenu

Viewの長押しで表示されるメニューを構成する。

・onCreateContextMenu:ContextMenuの構成を初期化する
・onContextItemSelected:ContextMenuの選択状況を見て、適切なアクションを起こすために呼び出される


ex)

public class MainActivity extends Activity {
    @Override
    protected void onStart() {
        super.onStart();
        // View に長押しメニュー用のコールバックを設定する
        // 実際には、View に OnCreateContextMenuListener を設定するだけ
        // 登録処理を Activity が肩代わりしている
        View helloWorld = findViewById(R.id.HelloWorld);
        registerForContextMenu(helloWorld);
    }
    @Override
    protected void onStop() {
        // View に設定した長押しメニュー用のコールバックを解除する
        View helloWorld = findViewById(R.id.HelloWorld);
        unregisterForContextMenu(helloWorld);
        super.onStop();
    }
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        // ここで、長押しメニューで利用するメニューリソースを読み込む
        super.onCreateContextMenu(menu, v, menuInfo);
    }
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        // ここで、選択されたメニューリソースに対応するイベント処理を実行する
        return super.onContextItemSelected(item);
    }
}

●Viewの状態とコールバックメソッド


View には、以下のような「状態(State)」が定義される。
View の種類によって、取り得る状態は様々。たとえばクリックされたとき、フォーカスがあたったとき、のActionを実施するために必要である。

□Viewの状態

・normal:何もしていない
・enabled:Viewがユーザ操作を受け付ける状態
・focused:Viewがユーザ操作によってフォーカスを持っている状態
・selected:Viewがユーザ操作によって選択されている状態
・checked:Viewがユーザ操作によってチェックされている状態
・pressed:Viewがユーザ操作によって押されている(クリック、タップ)状態

上記の各状態について、Observer パターンでイベントを監視する仕組みがある。
監視するためのオブジェクトの登録方法によって、Activityのライフサイクルに合わせて監視オブジェクトの管理をする必要がある。
以下のようなObserver(リスナー)がある。

・OnClickListener:View をタップした時に呼び出されるイベントを拾うためのObserver
・OnLongClickListener:Viewを長押ししたときに呼び出されるイベントを拾うためのObserver
・OnFocusChangedListener:Viewのフォーカスが移動したときのイベントを拾うためのObserver
・OnCheckedChangeListener:CheckBoxなどで、チェック状態が変化したときのイベントを拾うためのObserver
・TextWatcher:EditTexdtなどで、入力テキストが変更された時のイベントを拾うためのObserver

【Notice】TextWatcherは、ActivityやFragmentのライフサイクルに合わせて、適宜Viewへの登録と解除を行う。

ex)

public class MainActivity extends Activity {
    private TextWatcher mTextWatcher = new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {}
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
        @Override
        public void afterTextChanged(Editable s) {}
    };
    @Override
    protected void onStart() {
        super.onStart();
        // ライフサイクルに合わせて、Observer オブジェクトを登録する
        TextView helloEdit = (TextView) findViewById(R.id.HelloEdit);
        helloEdit.addTextChangedListener(mTextWatcher);
    }
    @Override
    protected void onStop() {
        // ライフサイクルに合わせて、Observer オブジェクトを解除する
        TextView helloEdit = (TextView) findViewById(R.id.HelloEdit);
        helloEdit.removeTextChangedListener(mTextWatcher);
        super.onStop();
    }
}

【参考】
https://github.com/mixi-inc/AndroidTraining/wiki/2.05.-ActionBar%E3%81%A8%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%A9%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%88%B6%E5%BE%A1

0 件のコメント:

コメントを投稿