MatsuriTaikaiで優勝しました。Developersのフラグメントを訳しました。Developersの翻訳をやっているけれど、最初は翻訳サイト頼みだったのがだいぶ辞書で単語の意味を調べるだけで翻訳できるようになってきました。達成感があってとっても楽しいです。原文FragmentFragmentはActivityの振る舞いやUIの一部を表現します。マルチペインユーザーインターフェイスを構築するために一つのActivityに複数のFragmentを組み込めます。複数のActivityでFragumentを再利用できます。FragmentはActivityのモジュールセクションとして考えることが出来ます。それはライフサイクルを持ち、インプットイベントを受信し、Activityが実行中に追加したり、削除することが出来ます。Fragmentは常にActivityに埋めこまれている必要があります。ライフサイクルはホストActivityのライフサイクルの影響を直接受けます。Activityがpausedされたとき、その中にある全てのFragmentも同様にpausedされます。Activityが破棄されるとき、Fragmentも同様に破棄されます。Activityが実行される間(ライフサイクルはresumed状態)追加したり、削除するなどFragmentを独立して操作することが出来ます。フラグメントトランザクションを実行する時、Activityが管理するバックスタックにそれを追加できます。Activityの各バックスタックエントリーはフラグメントトランザクションの発生した記録となります。バックスタックはユーザーが戻るボタンを押すことでFragmentのトランザクションを戻せる(逆方向の操作)ようにします。Activityのレイアウトファイル内でFragmentエレメントを宣言するか、アプリケーションコードで既存のViewGroupに加えることでActivityレイアウトにFlagmentを挿入できます。FragmentはActivityレイアウトの一部である必要はありません。FragmentをActivityの非表示ワーカーとして使うことも出来ます。このドキュメントは、FragmentがActivityのバックスタックに加えられるとき、どうやってFragmentがその状態を保存するか、Activityとその他のFragmentでイベントを共有すること、アクションバーを活用する方法、その他Fragmentを使ったAplicationの構築方法を説明します。"Honeycomb")でFragmentを追加しました。タブレットの画面は携帯電話よりとても大きいので、UIの構成要素を入れ替える多くの余地があるからです。FragmentはView階層の複雑な変更を管理する必要なく、そのようなデザインが使用できます。ActivityのレイアウトをFragmentに分けることによって、実行時にActivityの表示を変えたりActivityが管理するバックスタックに変化を保存できるようになります。ニュースアプリケーションは一つのActivityで左に記事リストを表示させたfragment、右に記事の内容を表示させた別のfragment、両方のFragmentを並んで表示させることができます。それぞれのFragmentはそれ自身が自分のライフサイクルコールバックメソッドと入力イベントを取り扱います。図1のように一つのActivity内で記事を選び、読むことが出来ます。典型的な二つのActivityに分かれた二つのユーザーインターフェイス部品を、Fragmentを使って一つのActivityにまとめた例フラグメントはアプリケーション内でモジュール化されで再利用出来るコンポーネントです。Fragmentは自分のライフサイクルコールバックを使って自身のレイアウトと振る舞いを確立しているので、複数の異なるActivityで同じFragmentを使う事が出来ます。異なるスクリーンサイズでユーザーエクスペリエンスを適合させるためにこれは特に重要です。十分に大きなディスプレイの場合のみ複数のFragmentを一つのActivityに含め、そうでないときは異なるFragumentごとに異なるActivityを開始します。Aに含めることが出来ます。電話など普通サイズのディスプレイには両方のFragmentを含める空間がありません。このようにアプリケーションは図1で示す両方のデザインパターンをサポートします。Fragmentを作るFragmentを作るにはFragment(または既存のFragmentのサブクラス)のサブクラスを作ります。FragmentのコードはActivityにとても似ています。onCreate(),onStart(),onPause()そしてonStop()などActivityと同じコールバックメソッドを持ちます。実のところ既存のアプリケーションからFragmentを使うように移行したいならば、単にFragmentのそれぞれのコールバックメソッドにActivityのコールバックメソッドのコードを移動するだけでいいかもしれません。通常、以下のライフサイクルを実装する必要があります。onCreate()Fragmentを作成したとき、システムから呼ばれます。pausedまたはstoppedから再開する時に必要なFragmentのコンポーネントを初期化します。onCreateView()Fragmentのユーザーインターフェイスが最初に描画されるときシステムから呼ばれます。Fragmentのユーザーインターフェイスを描画するために、このメソッドはFragmentLayoutのルートViewを返す必要があります。UIを持たないFragmentの場合Nullを返すことが出来ます。onPause()ユーザーがFragmentから離れようとしている場合、(Frƒagmentが破棄されるとは限りません)システムは最初にこのメソッドを呼びます。通常、ユーザーセッションを越えるあらゆる変化を確定させる必要があります。(ユーザーがもどってこないことがあるため)Fragmentのためには、ほとんどのアプリケーションは少なくとも上記3つのメソッドを実装する必要があります。Fragmentの様々なライフサイクルを扱うためには他にも使用しなければならないコールバックメソッドがあります。Fragmentのライフサイクルをハンドリングするの章で全てのライフサイクルのコールバックメソッドを解説しています。基本的なFragmentクラスの代わりに継承した方が良い可能性があるサブクラスがあります。DialogFragmentフローティングダイアログを表示します。ActivityクラスのDialogヘルパーメソッドを置き換えるものです。Activityが管理するFragmentのバックスタックに組み込むことが出来て、ユーザーが除外されたFragmentに戻ることを許可するためです。ListFragmentアダプタ(SimpleCursorAdapter等)で管理されるアイテムのリストを表示します。ListActivityに似ています。リストビューを管理するために、クリックイベントをハンドリングするコールバックonListItemClickなどのメソッドを提供します。PreferenceFragmentPreferenceオブジェクトリストの階層を表示します。PreferenceActivityに似ています。これは設定Activityを作成する際に使用します。フラグメントのライフサイクル(Activity実行中)ユーザーインターフェイスの追加Fragmentは大抵Activityのレイアウトに影響しユーザーインターフェイスの一部となります。Fragmentにレイアウトを提供するためにonCreateView()コールバックメソッドを実装する必要があります。それはFragmentのレイアウトを描画するときにAndroidシステムより呼ばれます。実装したメソッドはFragmentレイアウトのルートViewを返す必要があります。ノート;もし、ListFragmentを継承した場合、標準でonCreateView()がListViewを戻します。そのため、あなたはそれを実装する必要がありません。onCreateView()でレイアウトを返すために、XMLに記載したレイアウトリソースをインフレートすることが出来ます。それを手助けするためにonCreateView()はLayoutInflaterオブジェクトを提供します。これはFragmentを継承したクラスがexample_fragment.xmlファイルからレイアウトを読み込んでいます。}}onCreateView()に渡されるcontainerパラメータは(ActivityLayoutによる)親のViewGroupです。Fragmentのレイアウトはこれに入ります。savedInstanceStateパラメータはFragmentが再開するときに前回のFragmentのデータを提供するバンドルです。(状態の復帰はFragmentのライフサイクルをハンドリングするの章で議論されます)inflate()メソッドは3つの引数を取ります。インフレートさせたいレイアウトリソースのレイアウトIDインフレートレイアウトの親ViewGroups。システムがインフレートされたレイアウトの(親として指定される)ルートviewにレイアウトパラメータを適用するためにcontainerを渡すことが重要です。インフレートレイアウトがインフレート中に(2番目のパラメータで指定した)viewGroupに付いている必要があるかどうかを表すブーリアン。(このケースではこれはFalseです。システムは既にインフレートされたレイアウトをコンテナに入れているので、)ここまで、レイアウトを提供するFragmentをどうやって作るかを説明しました。次はActivityにFragmentを追加するのに必要なことを説明します。ActivityにFragmentを追加する。Fragmentは通常ホストActivityのUIの一部を提供します。それはActivityのView階層全体一部として組み込まれます。ActivityレイアウトにFragmentを追加する2つの方法があります。Activityのレイアウトファイル内にFragmentを宣言するこの場合ビューのようにFragmentのレイアウトプロパティを指定することが出来ます。1つのActivityに2つのFragmentを記載するレイアウトファイルは次のとおりです。/></LinearLayout>fragmentのandroid:name要素にlayoutに実装するFragmentのクラスを記載します。システムがこのActivityレイアウトを作るとき、レイアウトで指定されたFragmentをインスタンス化し、それぞれのレイアウトを取得するためにonCreateView()メソッドを呼びます。システムFragmentが返したViewを直接Elementの場所に挿入します。Activityが再開されたとき、Fragmentをリストア出来るようにそれぞれのFragmentはユニークなIDが必要です。(このIDはFragmentを削除するるなどのトランザクションを行うときにFragmentを取得するのに使用できます。)FragmentのためにIDを振り分ける3つの方法があります。・android:id属性に一意のIDを付与する・android:tag属性に一意の文字列を付与する。・もしあなたが上記二つのどちらも付与しない場合、システムはcontainerビューのIDを使用する。既存のViewGroupにプログラムでFragmentを追加する。Activityが実行中、いつでもactivityレイアウトにFragmentを加えることが出来ます。Fragmentを置くViewGroupを指定する必要があるだけです。フラグメントに関する一連の作業(フラグメントを追加したり、削除したり、置き換えるなど)を行うにはFragmentTransactionが提供するAPIを使用する必要があります。下記の方法でActivityよりFragmentTransactionのインスタンスを取得できます。Fragment)メソッドを使用します。追加するFragmentと追加されるViewGroupを指定します。fragment);fragmentTransaction.commit();最初の引数はFragmentが追加されるViewGroupのリソースIDです。次のIDは追加するFragmentです。FragmentTransactionで変更作業を行った場合、エフェクトの変化のためにcommit()メソッドをコールする必要があります。上記ではユーザーインターフェイスを提供するためにFragmentをActivityに加える方法を示しました。バックグラウンドでの挙動をActivityに提供するためにユーザーインターフェイスを表示すること無いFragmentを使うことも出来ます。String)(intのViewIDではなくstringのtagを使用します)。これでFragmentを追加できます。ActivityのViewと結びついていないため、onCreateView()は呼ばれません。そのためこのメソッドを実装する必要はありません。厳密には文字列のタグはユーザーインターフェイスを含まないFragmentのためだけにあるわけではありません。ユーザーインターフェイスを持つFragmentでも文字列のタグを渡すことが出来ます。Fragmentにユーザーインターフェイスがない場合、文字列のタグはFragmentを確認する唯一の方法です。tag)を使用する必要があります。ユーザーインターフェイスのないFragmentをActivityのバックワーカーとして使う例はFragmentRetainInstance.javaを見てください。Fragmentの管理Activity内のFragmentを管理するにはFragmentManagerを使用する必要があります。ActivityからgetFragmentManager()をコールしてください。FragmentManagerでは以下のことが出来ます。(ユーザーインターフェイスを持たないFragment)でActivityに入っている既存のFragmentを取得する。listener)でバックスタックの変更リスナーを登録する。多くの情報はFragmentManagerクラスのドキュメントを参照してください。前章で述べたように、Fragmentを追加したり削除するトランザクションのためにFragmentManagerでFragmentTransactionを開くことが出来ます。FragmentTransactionの演出Activity内でFragmentを使う素晴らしい特徴は、ユーザーのインタラクションに応じてFragmentの追加・削除・置き換え・その他アクションが行えるようになることです。FragmentTransactionのAPIによる、Activityにコミットされる変化の各セットはトランザクションと呼ばれます。Activityが管理するバックスタックへ各トランザクションを保存することが出来、ユーザーがFragmentの変化を戻すことが出来ます。(Activityを戻るときに似ています)FragmentManagerによるFragmentTransactionを取得するには以下のようにします。fragmentManager.beginTransaction();各トランザクションは同時に変更を行いたい一組の操作です。add(),remove()そしてreplace()などのメソッドでどのような変化を行いたいかトランザクションにセットします。Activityに各トランザクションを適用するためにcommit()をコールします。commit()をコールする前に、addToBackStack()をコールした方がいい時もあります。このバックスタックはActivityに管理され、そしてユーザーが戻るボタンを押したときに以前のFragmentの状態に戻ることを許します。これは一つのFragmentを他のFragmentと入れ替え、以前の状態をバックスタックに保存する例です。IDにより特定されるレイアウトコンテナのFragmentと置き換わります。addToBackStack()を呼ぶことで、置き換えるTransactionをバックスタックに保存することが出来て、ユーザーは戻るボタンを押すことで、トランザクションを巻き戻し、以前のFragmentに戻すことが出来ます。他のadd()やremove()など複数の変更をトランザクションに追加し、addToBackStack()を読んだら、全てのcommit()以前の状態が一つのトランザクションとしてバックスタックに追加され、戻るボタンにより全てが同時に戻ります。変更をFragmentTransactionに追加する処理で重要なのは次のことだけです。最後にcommit()を呼ぶ必要がある。複数のFragmentを同じコンテナに追加したら、追加する順番でView階層を決定します。Fragmentを削除するトランザクション時にaddToBackStack()を呼ばなかったら、トランザクションがコミットされるときにFragmentは破棄されます。ユーザーは戻ることが出来ません。addToBackStack()を呼んでいたら、Fragmentはstopされます。ユーザーが戻るときresumeされます。各フラグメントのトランザクションをアニメーションさせるにはsetTransition()をコミットの前に呼ぶcommit()が呼ばれても即時にTransactionが実行されるわけではありません。スレッドが実行可能になるまでActivityのUIスレッド(メインスレッド)にスケジュールされます。executePendingTransactions()をUIスレッドから呼ぶことでcommit()の処理を即座に反映させることができます。これは普通、他のスレッドのジョブに依存するようなことがない限り必要ありません。警告:commit()でトランザクションをコミットできるのは、(ユーザーがActivityから離れ)状態を保存する前までです。それ以降にcommitを試みると例外がスローされます。これはActivityの復元時にコミットより後の状態が失われてしまうおそれがあるためです。Activityとのやり取りFragmentはActivityから独立し、複数のActivityに含めることすらできるが、実際のところ、そのインスタンスはそれが含まれるActivityと連携します。具体的には、FragmentはActivityのインスタンスへgetActivity()を使ってアクセスできます。簡単に下記のActivityレイアウトのViewをさがす例のように行うことができます。getActivity().findViewById(R.id.list);同様に、ActivityからFragmentManagerのfindFragmentByIdかfindFragmentByTagを使ってFragmentの参照を取得し、Fragmentのメソッドを呼び出せます。getFragmentManager().findFragmentById(R.id.example_fragment);Activityへのイベントコールバックの作成ActivityとFragmentでイベントを共有する必要がある時もあります。そのためにはFragmentでcallbackインターフェイスを宣言して、ホストのActivityでそれを実装させると良いです。そのとき、インターフェイスを介してActivityが受け取るコールバックによりレイアウトに内包する他のFragmentと必要な情報を共有することが出来ます。Aは記事が選択されたときActivityにそれを伝える必要があります。することでFragmentBに記事を表示するように伝えることが出来ます。このケースでは、OnArticleSelectedListenerインターフェイスをFragmentAの中で宣言しています。...}そのFragmentをホストする、ActivityがOnArticleSelectedListener()インターフェイスを実装し、onArticleSelected()をオーバーライドすることでfragmentAのイベントをfragmentBに通知します。AのonAttach()コールバックメソッド(システムがActivityにFragmentを追加するときにコールされます)で引数として渡されたActivityをOnArticleSelectedListenerにキャストし、インスタンスとする具体例を示します。...}もし、Activityがインターフェイスを実装しなかったら、FragmentはClassCastExceptionをスローします。AはOnArticleSelectedListenerインターフェイスによって宣言されたメソッドを呼び出すことでイベントをActivityと共有出来ます。AがListFragmentを継承していると、ユーザーがクリックする度にFragmentのonListItemClick()メソッドがシステムから呼ばれ、そのなかでonArticleSelected()を呼ぶことでActivityとイベントを共有します。...}onListItemClick()の引数IDはクリックされたアイテムの行IDです。Activity(または他のFragment)はアプリケーションのContentProvider.を使用して記事を探し出します。Providersドキュメントにあります。ActionBarにアイテムを追加する。FragmentはonCreateOptionMenu()を実装することでActivityのオプションメニュー(そして結果としてアクションバーにも)メニューアイテムを提供します。このメソッドが呼ばれるようにするにはonCreate()内でsetHasOptionsMenu()を呼び出し、Fragmentはオプションメニューにアイテムを追加したいことを明示する必要があります。onCreateOptionsMenu()を受け取りません。)オプションメニューの既存のメニューアイテムへFragmentによる全てのアイテムが追加されます。onOptionsItemSelected()コールバックを受信します。registerForContextMenu()を呼び出すことでコンテキストメニューにFragmentレイアウトのviewを登録できます。それによりユーザーがコンテキストメニューを開くとonCreateContextMenu()が呼び出され、ユーザーがアイテムを選択するとFragmentはonContextItemSelected()を受信します。ノート:Fragmentは各追加されたメニューアイテムからアイテムが選択されたコールバックを受けるが、ユーザーがメニューアイテムを選択したときにそれぞれのコールバックを最初に受けるのはActivityです。Activityによるon-item-selectedコールバックの実装が選択されたアイテムをハンドルしないならば、イベントはFragmentのコールバックに渡されます。これはオプションメニューとコンテキストメニューにおける事実です。Barを見てください。FragmentのライフサイクルをハンドリングするFragmentライフサイクルの管理は、Activityのライフサイクル管理と似ています。Activityに似てFragmentは3つの状態を持つことが出来ます。ResumedFragmentは実行中のActivity上で表示されます。Paused他のActivityが全面で動きフォーカスされています。Fragmentと、Fragmentを含むActivityは生きておりまだ表示されています。(全面のAcitivityは部分的に半透明であるか、スクリーン全体を覆ってはいません)StoppedFragmentは表示されていません。ホストのActivityがStoppedしているか、FragmentがActivityから取り除かれているがバックスタックに加えれられています。Fragmentはまだ生きています。(すべての状態とメンバーの情報はシステムが持っています)しかしながら長い間非表示であったり、Activityがkillされるとkillされます。onActivityCreated()で復元します。状態を保存するより詳細な情報はActivitiesドキュメントを見てください。ActivityとFragmentのライフサイクルにおける興味深い違いは、バックスタックにどのように保存されるかです。Activityは標準でStoppedされたときシステムによりActivityのバックスタックに置かれます。(それによりユーザーは戻るボタンで前に戻ることができます。Stackに記載されています)しかし、Fragmentは削除されるときにaddToBackStack()を呼び、インスタンスを保存することを明示したときのみ、ホストが管理するActivityのバックスタックに置かれます。他の点ではFragmentライフサイクルの管理はActivityのライフサイクルの管理にとても似ています。lifecycleと同じ方法でFragmentも行うことができます。Activityのライフサイクルがフラグメントのライフサイクルにどのように影響を及ぼすかは理解する必要があります。Activityライフサイクルとの調和Activityが各ライフサイクルのコールバックを受けるとFragmentのコールバックも同様になるように、ActivityのライフサイクルはFragmentのライフサイクルへ直接影響します。ActivityがonPause()を受信するとアクティビティ内の各FragmentはonPauser()を受信します。Fragmentは多少追加のライフサイクルコールバックを持っていますが、これはActivityがFragmentのUIを構築、破棄する時にActivityとの独自の相互作用をハンドルします。次は加えられるコールバックメソッドです。onAttach()FragmentがActivityに結びつくときに呼ばれます。(Activityが引数として渡されます)onCreateView()Fragmentと結びつくView階層を作るために呼ばれますonActiveCreated()ActivityのonCreate()メソッドからもどってきたときに呼ばれます。onDestroyView()Fragmentに結びつくView階層が削除されるとき呼ばれます。onDetach()ActivityからFragmentが切り離されるときに呼ばれます。図3ActivityライフサイクルがFragmentLifecycleに与える影響ホストActivityに影響されるFragmentライフサイクルの流れを描いたのが図3です。この図はActivityの状態変化によりFragmentのどのメソッドが呼ばれることがあるかを見ることが出来ます。ActivityがonCreate()コールバックを受け取ったら、Activity内のFragmentはonActivityCreated()コールバックまで呼ばれます。一度Activityがresumed状態になると、あなたは自由にFragmentをActivityから追加したり削除したり出来ます。それゆえ、Activityのresume状態は独立してFragmentのライフサイクルを変更できる唯一の状態です。Activityがresume状態から離れると、FragmentはまたActivityのライフサイクルにより呼び出されます。例ドキュメントで議論した内容をまとめます。これは1つのActivityが2ペインレイアウトを作るために2つのFragmentを使用する例です。Activityは下のシェイクスピアの演劇タイトルリストを表示するFragmentとリストで選択された演劇の概要を表示する物を含みます。それはスクリーンの設定により、異なるFragmentの設定を提供する方法も含みます。Activityのための完全なソースコードはFragmentLayout.javaに含まれます。通常通りにActivityはonCreate()でレイアウトを適用します。setContentView(R.layout.fragment_layout);}レイアウトはfragment_layout.xmlを適用します。/></LinearLayout>このレイアウトを使用してActivityがレイアウトを呼ぶとシステムはTitleFragment(演劇のタイトルリスト)をインスタンス化し、FrameLayout(演劇の概要を表示することになる)はスクリーンの右側の空間を空のままで埋める。ユーザーがアイテムを選択するとFrameLayoutの位置にFragmentを置くことになる。全てのスクリーン構成がタイトルのリストと記事を並べて表示するのに足りるわけではありません。res/layout-land/fragment_layout.xmlとして保存しディスプレイが横向きの時だけ反映されるようにします。そのため縦向きの画面でシステムが使用するレイアウトをres/layout/fragment_layout.xml:として保存します。/></FrameLayout>このレイアウトはTitleFragmentのみをふくんでいます。これにより、デバイスが縦向きの時は演劇のタイトルのみが表示されます。そのため、この設定でユーザーがリストをクリックした場合は、アプリケーションは2つ目のFragmentを呼ぶ代わりに新しいActivityを開始して概要を表示します。次に、Fragmentクラスがどうやってこれを行うかについて見ていきます。viewの仕事の多くは継承元に委ねます。このコードを注意深く見ると、ユーザーがリストアイテムをクリックしたときの振る舞いが、あることに気づきます。2つのレイアウトのどちらが有効であるかにより、同じActivityに新しい詳細を見せるFragmentを作成し描画(FrameLayoutにFragmentを追加する)するか、(Fragmentを表示することが出来る)新しいActivityを開始する。}}第二のフラグメント、DetailsFragmentはTitlesFragmentのリストで選択された演劇の概要を表示します。(これはDetailsFragmentsが所属する場所です)が含まれていなかったら、アプリケーションはDetailsActivityを開始し、アイテムのコンテンツを表示します。これは、単純に演劇の概要を表示するDetailsFragmentを埋め込み縦向きのスクリーンに表示するDetailsActivityです。}}もし、画面が横向きであれば自分自身のActivityを終了させています。そのため、メインのActivityが引き続きDetailsFragmentと並んでTitlesFragmentを表示できます。これは、ユーザーが最初にDetailsActivityを縦向きで表示していたが、横向きに回転させたときに発生します。(その時、現在のActivityは再起動されます)Fragmentsを使うより多くのサンプル(及び事例の完璧なソース)はApiDemos()を見て下さい。MatsuriTaikaiで優勝しました。