==[[Android Fragment]]==
[[Android]] | [[Android Tips]] |
*http://developer.android.com/guide/components/fragments.html
*フラグメントを自身のUIを持たない、アクティビティのための不可視なワーカーとして使うこともできる
===[[デザイン]]===*Androidでは、フラグメントをAndroid30[[Android]]では、フラグメントを[[Android]]30(API Level11)で導入した。*一義的には、タブレットなどの大画面でさらに動的で柔軟なUIデザインをサポートするため。一義的には、タブレットなどの大画面でさらに動的で柔軟なUI[[デザイン]]をサポートするため。
*タブレットのスクリーンは、ハンドセットと比較して十分に大きく、ユーザーとやりとりするUIコンポーネントのための場所が残されている。
*フラグメントはこのようなビュー階層の複雑な変更の管理が必要内容にデザインされている。フラグメントはこのようなビュー階層の複雑な変更の管理が必要内容に[[デザイン]]されている。
*アクティビティレイアウトにフラグメントを投入することによって、レイアウトに起動中のアクティビティの表示やそれら変更の維持管理を変更できる様になる。
*言い換えれば、記事のリスト表示と記事を読むことを一つの同じアクティビティで行うことができるということ。
*フラグメントを再利用可能なモジュールコンポーネントとしてデザインすべき。フラグメントを再利用可能なモジュールコンポーネントとして[[デザイン]]すべき。
*それぞれのフラグメントは、自分自身のレイアウトを定義し、それぞれの振る舞いを自身のライフサイクルコールバックに持つため。
*一つのフラグメントを複数のアクティビティに組み込むことができるので、再利用可能かつ、フラグメント間で、直接操作し合うことは行うべきではない。
*モジュール化されたフラグメントは、フラグメントの組合せを異なったスクリーンサイズにおいて可能にする
*アプリケーションにタブレットとハンドセットをサポートするようにデザインする場合、フラグメントを可能なスクリーンスペースに依存したユーザーエクスペリエンスに応じた、別のレイアウト定義に再利用できる。アプリケーションにタブレットとハンドセットをサポートするように[[デザイン]]する場合、フラグメントを可能なスクリーンスペースに依存したユーザーエクスペリエンスに応じた、別のレイアウト定義に再利用できる。
===フラグメントの生成===
*フラグメントを生成するには、Fragment のサブクラスを作成する必要がある。
*Fragment クラスは、Activity クラスは、Acti[[vi]]ty によく似ている。
*アクティビティと同じく、onCreate(),onStart(),onPause,onStop()といったコールバックメソッドを持つ
*実際、既存のAndroidアプリケーションをフラグメントを利用するようにコンバートする場合、単純にアクティビティのコールバックメソッドをそれぞれフラグメントのメソッドに移動する。実際、既存の[[Android]]アプリケーションをフラグメントを利用するようにコンバートする場合、単純にアクティビティのコールバックメソッドをそれぞれフラグメントのメソッドに移動する。
*通常、少なくとも以下のライフサイクルメソッドを実装する
**onCreate():フラグメント生成時に呼ばれる。主要なコンポーネントの初期化、ポーズやストップから再開したときの処理を実装
*Fragmentクラスを継承する代わりに、いくつかのサブクラスを利用できる
**DialogFragment : フローティングダイアログ。アクティビティのダイアログヘルパーメソッドを利用するのの良い代替となる。
**ListFragment : アダプターにより管理されるアイテムをリストする。ListActivityと同様アダプターにより管理されるアイテムをリストする。ListActi[[vi]]tyと同様**PreferenceFragment : Preference オブジェクトの階層をリストとして表示する。PreferenceActivityと同様オブジェクトの階層をリストとして表示する。PreferenceActi[[vi]]tyと同様
===ユーザーインターフェースの追加===
<blockquote>ListFragmentのサブクラスである場合、デフォルトの実装では、ListViewを返すため、実装する必要はない</blockquote>
*onCreateView() からレイアウトを返すために、XMLで定義されたレイアウトリソースからViewを生成することができる。からレイアウトを返すために、[[XML]]で定義されたレイアウトリソースからViewを生成することができる。
*それを助けるために、onCreateView() は LayoutInflater オブジェクトを提供する
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate([[R]].layout.example_fragment, container, false);
}
}
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.news.ArticleReaderFragmentArticle[[R]]eaderFragment" android:id="@+id/viewer[[vi]]ewer"
android:layout_weight="2"
android:layout_width="0dp"
*アクティビティが起動している間はいつでも、アクティビティレイアウトにフラグメントを追加することができる。
*単純にフラグメントを追加するViewGroupを指定するだけ。
*アクティビティの中のフラグメントトランザクションアクティビティの中のフラグメント[[トランザクション]](フラグメントの追加、削除、置き換えなど)を作成するには、FragmentTransaction APIを利用する必要が有る。
*FragmentTransaction は、Actiityから、以下の様にインスタンスを取得できる。
FragmentManager fragmentManager = getFragmentManager()
*add()メソッドによって、フラグメントを追加することができる。
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add([[R]].id.fragment_container, fragment);
fragmentTransaction.commit();
*add()の最初の引数は、フラグメントを挿入すべきViewGroupのリソースID、2つめの引数は、追加するフラグメント
*バックスタックの変更リスナーを addOnBackStackChangedListener() で登録する
===フラグメントトランザクションの実行フラグメント[[トランザクション]]の実行===
*アクティビティでフラグメントを利用する上で主要な機能は、追加、削除、置き換え、他のアクションを実行する能力。
*アクティビティへコミットする変更セットのそれぞれついて、トランザクションが呼び出され、FragmentTransaction APIを利用してトランザクションを実行できる。アクティビティへコミットする変更セットのそれぞれついて、[[トランザクション]]が呼び出され、FragmentTransaction APIを利用して[[トランザクション]]を実行できる。*それぞれのトランザクションをアクティビティにより管理されるバックスタックへ保存することもできる。それぞれの[[トランザクション]]をアクティビティにより管理されるバックスタックへ保存することもできる。
*ユーザーは、フラグメントの変更を「戻る」ことができる。
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
*それぞれのトランザクションは、同時に実行したい変更のセットそれぞれの[[トランザクション]]は、同時に実行したい変更のセット*add(),remove()やreplace()などトランザクションメソッドが呼ばれたときに実行させたいすべての変更をセットアップできる。など[[トランザクション]]メソッドが呼ばれたときに実行させたいすべての変更をセットアップできる。*アクティビティにトランザクションを適用するには、commitアクティビティに[[トランザクション]]を適用するには、commit()する。
*しかしながら、commit()する前に、トランザクションをフラグメントトランザクションのバックスタックに追加するために、addToBackStackする前に、[[トランザクション]]をフラグメント[[トランザクション]]のバックスタックに追加するために、addToBackStack()を実行したい場合もあるだろう。
*バックスタックは、アクティビティにより管理され、ユーザーに直前のフラグメントの状態に戻ることを可能にする。
*以下は、どのようにフラグメントを置き換え、直前の状態をバックスタックに保持するかの例
// あたらしいフラグメントとトランザクションの生成あたらしいフラグメントと[[トランザクション]]の生成
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// fragment_container ビューを fragment に置き換え、
// トランザクションをバックスタックに積む[[トランザクション]]をバックスタックに積む transaction.replace([[R]].id.fragment_container, newFragment);
transaction.addToBackStack(null);
// トランザクションのコミット[[トランザクション]]のコミット
transaction.commit();
*newFragment は、R.id.fragment_container IDを置き換え、addToBackStack()を呼び出すことで、この置き換えトランザクションをバックスタックに保存する。を呼び出すことで、この置き換え[[トランザクション]]をバックスタックに保存する。*これにより、ユーザーがトランザクションをリバースし、直前のフラグメントにバックボタンで戻すことができる。これにより、ユーザーが[[トランザクション]]をリバースし、直前のフラグメントにバックボタンで戻すことができる。
*複数の変更をトランザクションに追加し、addToBackStack複数の変更を[[トランザクション]]に追加し、addToBackStack()を呼び出した場合、commit()を呼び出しすべての変更が適用される前のすべての変更がバックスタックに一つのトランザクションとして追加され、バックボタンでそれらすべてを元に戻すことができる。を呼び出しすべての変更が適用される前のすべての変更がバックスタックに一つの[[トランザクション]]として追加され、バックボタンでそれらすべてを元に戻すことができる。
*変更をFragmentTransactionに追加するのに、以下を除いて、順序は関係ない
**同じコンテナに複数のフラグメントを追加した場合、それらを追加した順序は、ビューの階層に出現する順序となる。
*もし、フラグメントを削除するトランザクションを実行したときに、addToBackStackもし、フラグメントを削除する[[トランザクション]]を実行したときに、addToBackStack() を呼ばなければ、フラグメントは、トランザクションのコミット時に破棄され、ユーザーは、戻ることができない。を呼ばなければ、フラグメントは、[[トランザクション]]のコミット時に破棄され、ユーザーは、戻ることができない。
*それに対して、addToBackStack()を呼び出した場合、フラグメントは停止され、ユーザーが戻る場合に、再開される。
<blockquote>それぞれのフラグメントトランザクションに、setTransactionそれぞれのフラグメント[[トランザクション]]に、setTransaction() を コミット前に呼ぶことによって、トランザクションアニメーションを適用できる。コミット前に呼ぶことによって、[[トランザクション]]アニメーションを適用できる。</blockquote>*commit() を呼び出すことは、トランザクションを直ちに実行することではない。を呼び出すことは、[[トランザクション]]を直ちに実行することではない。
*性格には、アクティビティのUIスレッドに直ちに実行するようにスケジュールする。
*しかしながら必要な場合、UIスレッドから直ちにトランザクションのcommitしかしながら必要な場合、UIスレッドから直ちに[[トランザクション]]のcommit()を実行するように、executePendingTransaction() を呼ぶことができる。*通常これは、トランザクションが、他のスレッドに依存していないかぎり、必要ではない。通常これは、[[トランザクション]]が、他のスレッドに依存していないかぎり、必要ではない。
<blockquote>注意:commit()でトランザクションをコミットできるのは、アクティビティの保存時まで。この時点を過ぎてcommitで[[トランザクション]]をコミットできるのは、アクティビティの保存時まで。この時点を過ぎてcommit()を試みると例外となる。なぜなら、コミット後の状態はアクティビティがリストアするときに失われてしまう</blockquote>
ため。