基本的な「フラグメントチュートリアル」パターンは次のようになります。
Fragments
であり、両方とも同じActivity
に存在します。Fragment
にリストActivity
があります。Activity
で新しいFragment
を起動します。(例: Dianne HackbornによるAndroid 3.0 Fragments API および Fragments API Guide )
両方のデバイスで、機能はFragments
にあります。 (シンプル)
Tabletでは、アプリ全体が1 Activity
、phoneには、many Activities
があります。
Activities
?に分割する理由はありますか問題このメソッドでは、メインのタブレットActivity
と別の電話Activities
で多くのロジックを複製します。
Fragments
インとアウトを切り替える同じロジックを使用して(異なるレイアウトを使用するだけで)両方のケースで1アクティビティモデルを保持するのは簡単ではないでしょうか?このように、ほとんどのロジックはFragments
自体に存在し、単一のActivity
しかありません-コードの重複が少なくなります。
また、ActionBarSherlock
について読んだことは、Fragments
の代わりにActivities
で最適に動作するようだということです(ただし、まだ動作していません)。
チュートリアルは単純化されていますか、またはこのアプローチの主要な何かを見逃していますか?
私たちはオフィスで両方のアプローチを成功裏に試しましたが、私はより大きなプロジェクトを始めようとしているので、できる限り自分で簡単にできるようにしたいと思っています。
関連する質問へのリンク:
質問に対する報奨金を開始しました-タブレットアクティビティと各電話アクティビティでアプリロジックを複製する必要がある理由についてまだ確信が持てません。
また、Squareの関係者による興味深い記事を見つけました。
チュートリアルが非常に単純化されていることに同意します。 Fragments
を紹介するだけですが、提案されているパターンには同意しません。
また、アプリのロジックを多くのアクティビティに複製することはお勧めできません( ウィキペディアのDRY原則 を参照)。
ActionBarSherlock
Fragments Demoアプリ( ここからダウンロード および ここからソースコード )で使用されるパターンを好みます。質問で言及されたチュートリアルに最も近いデモは、アプリの「レイアウト」と呼ばれるものです。またはFragmentLayoutSupport
ソースコード。
このデモでは、ロジックがActivity
からFragment
に移動されました。 TitlesFragment
には、実際にフラグメントを変更するためのロジックが含まれています。このように、各アクティビティは非常にシンプルです。アクティビティの内部にロジックが存在しない非常に単純なアクティビティを多数複製すると、非常に単純になります。
ロジックをフラグメントに入れることにより、複数回コードを記述する必要がなくなります;フラグメントがどのアクティビティに配置されていても利用可能です。これにより、基本的なチュートリアルで提案されているパターンよりも強力なパターンになります。
/**
* Helper function to show the details of a selected item, either by
* displaying a fragment in-place in the current UI, or starting a
* whole new activity in which it is displayed.
*/
void showDetails(int index)
{
mCurCheckPosition = index;
if (mDualPane)
{
// We can display everything in-place with fragments, so update
// the list to highlight the selected item and show the data.
getListView().setItemChecked(index, true);
// Check what fragment is currently shown, replace if needed.
DetailsFragment details = (DetailsFragment) getFragmentManager()
.findFragmentById(R.id.details);
if (details == null || details.getShownIndex() != index)
{
// Make new fragment to show this selection.
details = DetailsFragment.newInstance(index);
// Execute a transaction, replacing any existing fragment
// with this one inside the frame.
FragmentTransaction ft = getFragmentManager()
.beginTransaction();
ft.replace(R.id.details, details);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
}
else
{
// Otherwise we need to launch a new activity to display
// the dialog fragment with selected text.
Intent intent = new Intent();
intent.setClass(getActivity(), DetailsActivity.class);
intent.putExtra("index", index);
startActivity(intent);
}
}
ABS パターンのもう1つの利点は、多くのロジックを含むタブレットアクティビティにならないことです。つまり、メモリを節約できます。チュートリアルパターンは、より複雑なアプリで非常に大きなメインアクティビティにつながる可能性があります。いつでもそこに配置されるすべてのフラグメントのロジックを処理する必要があるためです。
全体として、多くのアクティビティの使用を余儀なくされていると考えないでください。コードを多くのフラグメントに分割し、それらを使用するときにメモリを節約する機会があると考えてください。
あなたは正しい軌道に乗っていると思います。 (そして、はい、チュートリアルは単純化されすぎています)。
タブレットレイアウトでは、単一のアクティビティを使用して、フラグメントを(複数の「ペイン」で)スワップインおよびスワップアウトできます。電話レイアウトでは、フラグメントごとに新しいアクティビティを使用できます。
そのようです:
多くの余分な作業のように思えるかもしれませんが、電話に複数のアクティビティを使用することで、基本的なアクティビティライフサイクルとインテントの受け渡しを可能にします。これにより、フレームワークがすべてのアニメーションとバックスタックを処理することもできます。
コードを削減するために、BaseActivity
を使用して、そこから拡張できます。
そのため、ユーザーがタブレットを使用している場合は、MyMultiPaneFragActivity
などを使用します。このアクティビティは、フラグメントからのコールバックを管理し、インテントを正しいフラグメント(検索インテントなど)にルーティングします。
ユーザーが電話を持っている場合は、ごくわずかなコードで通常のアクティビティを使用し、MyBaseSingleFragActivity
などを拡張できます。これらのアクティビティは、5〜10行のコード(非常に簡単な場合もあります)の非常に単純なものです。
トリッキーな部分は、ルーティングの意図などです。 *(編集:以下を参照)。
これが推奨される方法である理由は、メモリを節約し、複雑さと結合を減らすためだと思います。フラグメントをスワップアウトする場合、FragmentManager
はバックスタックのそのフラグメントへの参照を維持します。また、ユーザーにとって「実行」すべきものを簡素化します。また、このセットアップは、フラグメントのビューとレイアウトおよびロジックをアクティビティライフサイクルから切り離します。このように、フラグメントは、単一のアクティビティ内に、別のフラグメント(2ペイン)と並んで、または3ペインアクティビティなどに存在できます。
*通常のインテントルーティングを使用する利点の1つは、バックスタックのどこからでも明示的にアクティビティを起動できることです。 1つの例は、検索結果の場合です。 (MySearchResults.class)。
詳細についてはこちらをお読みください:
http://Android-developers.blogspot.com/2011/09/preparing-for-handsets.html
各フラグメントは別々のアクティビティで適切に動作する必要があるため、少し前もって作業する必要がありますが、通常は成果があります。つまり、さまざまなフラグメントの組み合わせを定義する代替レイアウトファイルを使用し、フラグメントコードをモジュール式に保ち、アクションバーの管理を簡素化し、システムにすべてのバックスタック作業を処理させることができます。
これに関するReto Meierの答えは、 このビデオ から dacityのAndroid Fundamentalsコース から取ったものです。
アプリをさまざまなアクティビティに分割した方がよい理由はいくつかあります。
- 単一のモノリシックアクティビティがあると、コードの複雑さが増し、読み取り、テスト、および保守が困難になります。
- インテントフィルターの作成と管理をより困難にします。
- 独立したコンポーネントを密結合するリスクが高まります。
- 単一のアクティビティに機密情報と安全に共有できる情報の両方が含まれている場合、セキュリティリスクが発生する可能性がはるかに高くなります。
経験則として、コンテキストが変わるたびに新しいアクティビティを作成することをお勧めします。たとえば、異なる種類のデータを表示したり、表示からデータ入力に切り替えたりします。
この方法の1つの問題は、メインのタブレットアクティビティと別の電話アクティビティで多くのロジックを複製することです。
マスター/ディテールパターンには、2つのアクティビティがあります。 1つは、両方のフラグメントを大きな画面で表示し、「マスター」フラグメントのみを小さな画面で表示します。もう1つは、小さな画面に「詳細」フラグメントを示しています。
詳細ロジックは、詳細フラグメントで結び付けられる必要があります。したがって、アクティビティ間の詳細ロジックに関連するコードの重複はありません。詳細アクティビティは、詳細フラグメントを表示するだけで、おそらくIntent
extraからデータを渡します。
また、ActionBarSherlockについて読んだことは、ActivityではなくFragmentsで最適に動作するようだということです(ただし、まだ動作していません)。
ActionBarSherlockはネイティブアクションバーの純粋なバックポートであるため、ActionBarSherlockはネイティブアクションバーよりもフラグメントと関係がありません。
「電話アプリを多くのアクティビティに分割する理由はありますか?」の最初の質問を参照してください。 - はい。それは単に利用可能なスペースに帰着するだけであり、タブレットは開発者により多くのスペースを与え、したがって開発者が1つの画面にもっと多くを置くことを可能にします。 Androidは、 アクティビティが画面を提供できる であることを示しています。そのため、タブレットの1つの大きな画面でできることは、すべてのフラグメントに十分なスペースがないため、携帯電話の複数の画面に広げなければならないことです。