連載
» 2011年08月23日 00時00分 公開

Androidで動く携帯Javaアプリ作成入門(24):Androidの画面の大きさの違いを解決するFragments (3/3)

[緒方聡,株式会社イーフロー]
前のページへ 1|2|3       

Fragment#getActivity()

 Fragmentが所属するActivityを取得します。

Fragment#getTag()

 Fragmentに割り当てたタグを取得します。ViewはIDによって管理されますが、FragmentはIDによる管理とタグによる管理が可能です。UIを持たないFragmentはIDを割り当てられないため、タグによって管理します。

Fragment#getFragmentManager()

 FragmentからFragmentManagerを取得します。

FragmentManager#beginTransaction()

 FragmentTransactionを取得します。

 Fragmentに対する、いわゆる画面遷移には、「トランザクション」という考え方を適用します。ここで取得したFragmentTransactionのメソッドを呼び出しても、即座にそれらを適用するわけではありません。後述する、FragmentTransaction#commit()を呼び出して、初めて適用されます。

FragmentTransaction#addToBackStack(String)

 トランザクションをバックスタックに追加します。現在のトランザクションをcommit()後に参照したい場合に追加しておきます。任意でこのトランザクションに名前を付けられますが、必要がなければnullを渡します。

FragmentTransaction#commit()

 トランザクションをコミットします。もし、addToBackStack(String)でトランザクションをバックスタックに追加している場合、このメソッドの戻り値としてバックスタックエントリのIDを」返します。

FragmentManager#popBackStack()

 addToBackStack()でスタックしたトランザクションを1つ戻します。ユーザによるバックキー押下と同様の処理を任意で行えます。

FragmentsをAndroidアプリに実装して使うには

 ここからは、Fragmentを使用するアプリのための、設定方法と実装方法について解説します。

レイアウト

 Fragmentを画面にレイアウトする方法は、Viewと同様、レイアウトXMLに設定するか、ソースコード上で追加するかを選べます。

レイアウトエディタのFragment 図8 レイアウトエディタのFragment

 レイアウトエディタには、「Fragment」という新たなレイアウトが追加されており、これをドラッグ&ドロップするだけで、レイアウトが行えます。

 レイアウトエディタでレイアウトした結果が以下です。

レイアウトエディタ上のデザイン 図9 レイアウトエディタ上のデザイン

 Fragmentをレイアウトするうえで重要なのは、Fragmentの幅と高さ、およびウェイトの設定です。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent">
  <fragment android:id="@+id/fragment1"
            android:layout_height="match_parent"
            android:layout_width="0dp" 【1】
            android:layout_weight="1" 【2】
            android:name="com.example.android.fragment.BookmarkFragment" />
  <fragment android:id="@+id/fragment2"
            android:layout_height="match_parent"
            android:layout_width="0dp" 【1】
            android:layout_weight="3" 【3】
            android:name="com.example.android.fragment.WebFragment" />
</LinearLayout>

 【1】では、左右に配置されるFragmentのそれぞれの幅を0dpに設定します。

 【2】では、左側のリストは幅のウェイトを1に設定します。

 【3】では、右側のブラウザは幅のウェイトを3に設定します。このようにすることで、画面サイズによらず、リスト:ブラウザ=1:3に保てます。

Fragmentの実装

 レイアウトXMLで指定したFragmentを実装します。ここでは、今回のサンプルの中から、オーバーライドした2つのメソッドを取り上げて解説します。

    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
        List<String> list = new LinkedList<String>();
        for (String[] bookmark : BOOKMARKS) {
            list.add(bookmark[0]);
        }
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, list);
        ListView listView = new ListView(getActivity());
        listView.setAdapter(adapter);
        return listView;
    }

 上記は、onCreateView()でFragmentに表示するViewを作成・初期化しているコードです。このクラスはListFragmentを継承しているため、メソッドに渡されている引数を一切使用していませんが、Fragmentから継承させた独自Fragmentの場合、別に作成したレイアウトと、LayoutInfraterで紐付ける必要があります。

 先にも述べたとおり、ListFragmentの場合はonActivityCreated()で初期化する方が賢明です。

    @Override
    public void onListItemClick(ListView l, View v, int position,long id) {
        if (position == 0) {
            getFragmentManager().popBackStack();
        } else {
            String url = BOOKMARKS[position][1];
            WebFragment web = new WebFragment(url);
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.replace(R.id.fragment2, web);
            ft.addToBackStack(null);
            ft.commit();
        }
    }

 上記はリストがクリックされた際に呼び出されるListFragment固有のイベントメソッドです。

 クリックされた場所が先頭なら、バックスタックからポップし、そうでなければ、新しいFragmentを作成し、既存のものと置き換え、トランザクションをバックスタックに追加しています。

 これだけの処理で、Android 2.xでは実現できなかった画面内の画面遷移が行えるようになります。

実は、もっと奥が深い「Fragments」

 Android 3.0から導入されたFragmentsを紹介しました。次回は、この機能がAndroid 1.6以降で使用可能になるAndroid Compatibility Packageを紹介します。

 なお、Fragmentは実はもっと奥が深いのですが、今回はここまでとし、スマートフォン向けとタブレット向けが統合されるIce Cream Sandwichが登場してから、Fragmentsとそれがもたらす可能性について再度取り上げる予定です。

 ちなみにJavaのSDKではありませんが、今回のようなFragmentsの考え方と違い、画面サイズごとに別のスタイルシートを当てて画面の大きさの違いを解決するという方法があります。Flex SDK 4.5.1の「CSS Media Query」機能です。詳細は、以下の記事をご参照ください。


「Androidで動く携帯Javaアプリ作成入門」バックナンバー
前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。