web-dev-qa-db-ja.com

ジレンマ:いつフラグメント対アクティビティを使うべきか:

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をできるだけ少なくするという哲学はすべての状況に当てはまるわけではありません。

736
Emil Adz

「UIが表示されたら、ActivityFragmentのどちらを使用するかがわかります。」はじめは意味がありませんが、やがてFragmentが必要かどうかを判断することができます。

私にとって非常に参考になると思う良い習慣があります。私が娘に何か説明しようとしている間に私に起こりました。

つまり、画面を表すボックスを想像してください。このボックスに別の画面をロードできますか?新しい箱を使用する場合、最初の箱から複数の商品をコピーする必要がありますか。答えが「はい」の場合は、Fragmentsを使用する必要があります。ルートのActivityには、それらを作成する時間を節約するために重複したすべての要素を保持できるため、ボックスの一部を置き換えるだけで済みます。

しかし 忘れないで あなたはいつもボックスコンテナ(Activity)を必要とするか、あなたのパーツは分散されるでしょう。内部に部品が入っているので1箱。

箱を悪用しないように注意してください。 Android UXの専門家は、(カテゴリを持つNavigation Drawerを扱うときのように)Activityを使用する代わりに、別のFragmentを明示的に読み込む必要がある場合にアドバイスします(YouTubeで見つけることができます)。 Fragmentsに慣れたら、彼らのすべてのビデオを見ることができます。さらにそれらは必須の資料です。

今すぐあなたのUIを見て、あなたがActivityまたはFragmentが必要かどうかを理解することができますか?あなたは新しい見方をしましたか?私はあなたがしたと思います。

251
sandalone

私の哲学はこれです:

絶対に必要な場合にのみアクティビティを作成してください。たくさんのフラグメントトランザクションをコミットするためにバックスタックを利用できるようにして、私は自分のアプリでできるだけ少ないアクティビティを作成しようとします。また、さまざまなフラグメント間の通信は、アクティビティ間でデータを送受信するよりもはるかに簡単です。

活動の移行は費用がかかりますね。少なくとも私はそう信じています - 古いアクティビティを破棄/一時停止/停止してスタックにプッシュし、それから新しいアクティビティを作成/開始/再開する必要があるためです。

フラグメントが導入されて以来、それは私の哲学です。

117

さて、グーグルの講義によると(多分 ここ 、覚えていないかもしれませんが)、コードの保守と管理が容易になるので、可能な限りいつでもFragmentsの使用を検討するべきです。

しかし、フラグメントをホストするアクティビティではフラグメント間をナビゲート/通信する必要があるため、場合によっては複雑になることがあります。

自分に最適なものを自分で決めるべきだと思います。通常、アクティビティをフラグメントに変換したり、その逆を行うことはそれほど難しくありません。

このディレマについての投稿を作成しました here 。さらに読みたい場合は。

54

なぜ私はすべてのケースで活動よりも断片化を好むのか。

  • 活動は高価です。 Fragmentでは、ビューとプロパティの状態は分離されています - フラグメントがbackstackにあるときはいつでも、そのビューは破棄されます。ですから、Activityよりもはるかに多くのFragmentsを積み重ねることができます。

  • Backstack操作FragmentManagerを使用すると、すべてのフラグメントをクリアしたり、フラグメントなどに挿入するよりも簡単に挿入できます。しかし、活動のために、それらのものを操作することは悪夢になるでしょう。

  • はるかに予測可能な ライフサイクル 。ホストアクティビティがリサイクルされていない限り。バックスタックのフラグメントはリサイクルされません。そのため、特定のフラグメントを見つけるためにFragmentManager::getFragments()を使用することが可能です(推奨されていません)。

24
Qylin

私の意見では、それは実際には関係ありません。考慮すべき重要な要素は

  1. uIの一部(メニューなど)を再利用する頻度
  2. タブレット用のアプリもありますか?

フラグメントの主な用途は、マルチペインアクティビティを構築することです。これはTablet/Phoneレスポンシブアプリケーションに最適です。

12
Isaac Urbina

Jetpack Single-Activity app が推奨されるアーキテクチャです。 ナビゲーションアーキテクチャコンポーネント で特に役立ちます。

ソース

8
Francis

アクティビティは、インテントを通じて共有および開始できるアプリケーションのブロック/コンポーネントであることを忘れないでください。したがって、アプリケーション内の各アクティビティは1種類のタスクのみを解決する必要があります。アプリケーションにタスクが1つしかない場合は、1つのアクティビティと必要に応じて多数のフラグメントだけが必要だと思います。もちろん、あなたは別のタスクを解決する将来の活動で断片を再利用することができます。このアプローチは、明確で論理的なタスクの分離になります。そして、あなたはフラグメントの異なるセットのために異なるインテントフィルタパラメータで1つのアクティビティを維持する必要はありません。要件に基づいて開発プロセスの設計段階でタスクを定義します。

8
guest

これ以外にも、起動したアクティビティが呼び出し側のアクティビティを暗黙的に破棄しないことを忘れないでください。もちろん、ユーザーがボタンをクリックしてページに移動し、そのページのアクティビティを開始して現在のページのアクティビティを破棄するように設定できます。これは多くのオーバーヘッドを引き起こします。私があなたにあげることができる最もよいガイドは:

**メインアクティビティとこのアクティビティを同時に開くのが理にかなっている場合にのみ、新しいアクティビティを開始します(複数のウィンドウを考えてください)。

複数のアクティビティがあることが理にかなっている場合の良い例は、Googleドライブです。主な活動はファイルエクスプローラを提供します。ファイルを開くと、そのファイルを表示するための新しいアクティビティが起動されます。最近開いたアプリボタンを押すと、開いている文書を閉じずにブラウザに戻ることができます。その後、最初の文書と並行して別の文書を開くこともできます。

8
TheHebrewHammer

私がしたこと:できるだけ断片を少なくする。残念ながら、それはほとんどの場合可能です。それで、私はたくさんの断片と少しの活動で終わります。私が気づいたいくつかの欠点:

  • ActionBarname__&Menu:2つのフラグメントのタイトル、メニューが異なる場合
    は扱いにくいでしょう。例:新しいフラグメントを追加するときにアクションバーのタイトルを変更できますが、backstackname__からポップするときに古いタイトルを復元する方法はありません。この場合、すべての断片にツールバーが必要になるかもしれませんが、私に信じてもらうと、時間がかかります。
  • startForResultname__が必要なとき、activityは持っていますがfragmentは持っていません。
  • デフォルトではトランジションアニメーションを持たない

これに対する私の解決策はActivityを wrap の中に使うことです。だから私たちは別々のアクションバー、メニュー、startActivityForResultname__、animation、...

6
I Love Coding

アクティビティに対するfragmentの大きな利点の1つは、フラグメントに使用されるコードをさまざまなアクティビティに使用できることです。したがって、アプリケーション開発でコードの 再利用性 が提供されます。

4
Sanchit Bhasin

あなたはそれらのうちの1つを自由に使用できます。
基本的に、あなたはあなたのアプリにとってどれが一番良いのかを評価しなければなりません。ビジネスフローをどのように管理するか、およびデータプリファレンスを保存/管理する方法について考えます。

フラグメントがガベージデータを格納する方法について考えてみましょう。フラグメントを実装すると、フラグメントを埋めるためのアクティビティルートができます。したがって、フラグメントが多すぎるアクティビティを多数実装しようとしている場合は、2つのコンテキストライフサイクルを操作している(おおまかに言っている)、アプリのパフォーマンスを考慮する必要があります。複雑さを覚えておいてください。

覚えておいてください:私はフラグメントを使うべきですか?どうして私はいけないの?

よろしくお願いします。

2
Franklin Hirata

私はより良いユーザーエクスペリエンスのためにフラグメントを使います。たとえば、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();
}

そうすれば、ユーザーは別のアクティビティに移動する必要がなくなります。

そして第二に、回転中にあなたがそれらを容易に扱うことができるので、私は断片を好みます。

1
Theo

それはあなたが本当に作りたいものによって異なります。例えばnavigation drawerはフラグメントを使います。タブもfragmentsを使います。もう一つの良い実装は、あなたがlistviewを持っているところです。電話機を回転させて行をクリックすると、アクティビティが画面の残りの半分に表示されます。個人的には、私はfragmentsfragment dialogsを使います。加えて、それらは回転においてより容易に扱われる。

1
Theo