Activities
は私のアプリケーションの単一画面を表すように設計されていますが、Fragments
はその中にロジックが埋め込まれた再利用可能なUIレイアウトとして設計されています。
それほど前までは、私はアプリケーションを開発したほうがいいと言って開発しました。私は自分のアプリケーションの画面を表すためにActivity
を作成し、ViewPager
またはGoogle Maps
にFragmentsを使用しました。私はめったに何度も再利用できるListFragment
や他のUIを作成しました。
最近私は2つだけのActivities
を含むプロジェクトに遭遇しました。1つはSettingsActivity
で、もう1つはMainActivity
です。 MainActivity
のレイアウトには、非表示のフルスクリーンUIフラグメントが多数表示されており、表示されているのは1つだけです。 Acitivty
ロジックでは、アプリケーションの異なる画面間に多数のFragmentTransitions
があります。
このアプローチについて私が気に入ったのは、アプリケーションがActionBar
を使用しているため、そのまま使用され、画面切り替えアニメーションとともに移動しないことです。これは、Activity
切り替えで発生します。これにより、それらの画面遷移がより滑らかになります。
だから私は私が求めているのはこのトピックに関するあなたの現在の開発方法を共有することであると思います、私はそれが一見したところ意見ベースの質問のように見えるかもしれません意見に基づくもの。
UPDATE(01.05.2014): このプレゼンテーションの後に Eric Burke from Square (たくさんの便利なツールがある素晴らしいプレゼンテーションです) Android開発者のためのものであり、私はSquareとは何の関係もありません。
http://www.infoq.com/presentations/Android-Design/
過去数ヶ月間の私の個人的な経験から、私は自分のアプリケーションを構築するための最善の方法はアプリケーションで flow を表すようになるフラグメントのグループを作成し、1つのActivity
に表示することです。そのため、基本的にはアプリケーション内にフローの数と同じ数のActivities
があります。そのようにしてアクションバーはすべてのフローの画面にそのまま残りますが、多くの意味をなすフローを変更することで再現されています。 Eric Burkeが述べているように、そして私が気づいているように、Activities
をできるだけ少なくするという哲学はすべての状況に当てはまるわけではありません。
「UIが表示されたら、Activity
とFragment
のどちらを使用するかがわかります。」はじめは意味がありませんが、やがてFragment
が必要かどうかを判断することができます。
私にとって非常に参考になると思う良い習慣があります。私が娘に何か説明しようとしている間に私に起こりました。
つまり、画面を表すボックスを想像してください。このボックスに別の画面をロードできますか?新しい箱を使用する場合、最初の箱から複数の商品をコピーする必要がありますか。答えが「はい」の場合は、Fragments
を使用する必要があります。ルートのActivity
には、それらを作成する時間を節約するために重複したすべての要素を保持できるため、ボックスの一部を置き換えるだけで済みます。
しかし 忘れないで あなたはいつもボックスコンテナ(Activity
)を必要とするか、あなたのパーツは分散されるでしょう。内部に部品が入っているので1箱。
箱を悪用しないように注意してください。 Android UXの専門家は、(カテゴリを持つNavigation Drawerを扱うときのように)Activity
を使用する代わりに、別のFragment
を明示的に読み込む必要がある場合にアドバイスします(YouTubeで見つけることができます)。 Fragments
に慣れたら、彼らのすべてのビデオを見ることができます。さらにそれらは必須の資料です。
今すぐあなたのUIを見て、あなたがActivity
またはFragment
が必要かどうかを理解することができますか?あなたは新しい見方をしましたか?私はあなたがしたと思います。
私の哲学はこれです:
絶対に必要な場合にのみアクティビティを作成してください。たくさんのフラグメントトランザクションをコミットするためにバックスタックを利用できるようにして、私は自分のアプリでできるだけ少ないアクティビティを作成しようとします。また、さまざまなフラグメント間の通信は、アクティビティ間でデータを送受信するよりもはるかに簡単です。
活動の移行は費用がかかりますね。少なくとも私はそう信じています - 古いアクティビティを破棄/一時停止/停止してスタックにプッシュし、それから新しいアクティビティを作成/開始/再開する必要があるためです。
フラグメントが導入されて以来、それは私の哲学です。
なぜ私はすべてのケースで活動よりも断片化を好むのか。
活動は高価です。 Fragmentでは、ビューとプロパティの状態は分離されています - フラグメントがbackstack
にあるときはいつでも、そのビューは破棄されます。ですから、Activityよりもはるかに多くのFragmentsを積み重ねることができます。
Backstack
操作FragmentManager
を使用すると、すべてのフラグメントをクリアしたり、フラグメントなどに挿入するよりも簡単に挿入できます。しかし、活動のために、それらのものを操作することは悪夢になるでしょう。
はるかに予測可能な ライフサイクル 。ホストアクティビティがリサイクルされていない限り。バックスタックのフラグメントはリサイクルされません。そのため、特定のフラグメントを見つけるためにFragmentManager::getFragments()
を使用することが可能です(推奨されていません)。
私の意見では、それは実際には関係ありません。考慮すべき重要な要素は
フラグメントの主な用途は、マルチペインアクティビティを構築することです。これはTablet/Phoneレスポンシブアプリケーションに最適です。
Jetpack 、 Single-Activity app が推奨されるアーキテクチャです。 ナビゲーションアーキテクチャコンポーネント で特に役立ちます。
アクティビティは、インテントを通じて共有および開始できるアプリケーションのブロック/コンポーネントであることを忘れないでください。したがって、アプリケーション内の各アクティビティは1種類のタスクのみを解決する必要があります。アプリケーションにタスクが1つしかない場合は、1つのアクティビティと必要に応じて多数のフラグメントだけが必要だと思います。もちろん、あなたは別のタスクを解決する将来の活動で断片を再利用することができます。このアプローチは、明確で論理的なタスクの分離になります。そして、あなたはフラグメントの異なるセットのために異なるインテントフィルタパラメータで1つのアクティビティを維持する必要はありません。要件に基づいて開発プロセスの設計段階でタスクを定義します。
これ以外にも、起動したアクティビティが呼び出し側のアクティビティを暗黙的に破棄しないことを忘れないでください。もちろん、ユーザーがボタンをクリックしてページに移動し、そのページのアクティビティを開始して現在のページのアクティビティを破棄するように設定できます。これは多くのオーバーヘッドを引き起こします。私があなたにあげることができる最もよいガイドは:
**メインアクティビティとこのアクティビティを同時に開くのが理にかなっている場合にのみ、新しいアクティビティを開始します(複数のウィンドウを考えてください)。
複数のアクティビティがあることが理にかなっている場合の良い例は、Googleドライブです。主な活動はファイルエクスプローラを提供します。ファイルを開くと、そのファイルを表示するための新しいアクティビティが起動されます。最近開いたアプリボタンを押すと、開いている文書を閉じずにブラウザに戻ることができます。その後、最初の文書と並行して別の文書を開くこともできます。
私がしたこと:できるだけ断片を少なくする。残念ながら、それはほとんどの場合可能です。それで、私はたくさんの断片と少しの活動で終わります。私が気づいたいくつかの欠点:
ActionBar
name__&Menu:2つのフラグメントのタイトル、メニューが異なる場合backstack
name__からポップするときに古いタイトルを復元する方法はありません。この場合、すべての断片にツールバーが必要になるかもしれませんが、私に信じてもらうと、時間がかかります。startForResult
name__が必要なとき、activityは持っていますがfragmentは持っていません。これに対する私の解決策はActivityを wrap の中に使うことです。だから私たちは別々のアクションバー、メニュー、startActivityForResult
name__、animation、...
アクティビティに対するfragment
の大きな利点の1つは、フラグメントに使用されるコードをさまざまなアクティビティに使用できることです。したがって、アプリケーション開発でコードの 再利用性 が提供されます。
あなたはそれらのうちの1つを自由に使用できます。
基本的に、あなたはあなたのアプリにとってどれが一番良いのかを評価しなければなりません。ビジネスフローをどのように管理するか、およびデータプリファレンスを保存/管理する方法について考えます。
フラグメントがガベージデータを格納する方法について考えてみましょう。フラグメントを実装すると、フラグメントを埋めるためのアクティビティルートができます。したがって、フラグメントが多すぎるアクティビティを多数実装しようとしている場合は、2つのコンテキストライフサイクルを操作している(おおまかに言っている)、アプリのパフォーマンスを考慮する必要があります。複雑さを覚えておいてください。
覚えておいてください:私はフラグメントを使うべきですか?どうして私はいけないの?
よろしくお願いします。
私はより良いユーザーエクスペリエンスのためにフラグメントを使います。たとえば、Buttonがあり、それを実行したい場合は、クリックしたときにWebサービスとしましょう。親ActivityにFragmentを添付します。
if (id == R.id.forecast) {
ForecastFragment forecastFragment = new ForecastFragment();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.main_content, forecastFragment);
ft.addToBackStack("backstack");
forecastFragment.setArguments(b);
ft.commit();
}
そうすれば、ユーザーは別のアクティビティに移動する必要がなくなります。
そして第二に、回転中にあなたがそれらを容易に扱うことができるので、私は断片を好みます。
それはあなたが本当に作りたいものによって異なります。例えばnavigation drawer
はフラグメントを使います。タブもfragments
を使います。もう一つの良い実装は、あなたがlistview
を持っているところです。電話機を回転させて行をクリックすると、アクティビティが画面の残りの半分に表示されます。個人的には、私はfragments
とfragment dialogs
を使います。加えて、それらは回転においてより容易に扱われる。