アクティビティとフラグメントの数は?


185

イントロ:

基本的な「フラグメントチュートリアル」パターンは次のようになります。

  1. タブレットでは、左側にリスト、右側に詳細があります。
  2. 両方とも Fragments同じ場所にありActivityます。
  3. 電話では、リストFragmentを1つにまとめActivityます。
  4. Activity詳細を指定して新しいものを起動しFragmentます。

(例:Dianne HackbornによるAndroid 3.0 Fragments APIFragments APIガイド

どちらのデバイスでも、機能はにありFragmentsます。(シンプル)

、タブレット、全体のアプリがある1Activityに、携帯電話がある多くのActivities


質問:

  • 電話アプリを多数に分割する理由はありActivitiesますか?

この方法の1つの問題は、メインのTablet と別のPhoneで多くのロジック複製することです。ActivityActivities

  • 両方のケースで1アクティビティモデルを保持する方が簡単で、同じロジックを使用して切り替えFragmentsます(異なるレイアウトを使用するだけ)。

このようにして、ほとんどのロジックはFragmentsそれ自体に存在し、Activityコードの重複が1つだけ少なくなります。

また、私が読んだのActionBarSherlockは、それがではFragmentsなく、最もうまく機能しているように見えるということですActivities(ただし、まだ機能していません)。

チュートリアルは単純化しすぎていますか、それともこのアプローチで重要な何かを見逃しましたか?


私たちはオフィスで両方のアプローチを成功させました-しかし、私はより大きなプロジェクトを開始しようとしていて、できるだけ自分のために物事を簡単にしたいと思っています。

関連する質問へのリンク:


アップデート

質問の報奨金を開始しました-タブレットアクティビティと各電話アクティビティでアプリロジックを複製する必要がある理由についてまだ確信がありません。

また、Squareのメンバーによる興味深い記事も見つかりました。これは一見の価値があります。


38
すばらしい、よく書かれた質問の+1。
Siddharth Lele 2012

それは最近私に多くの苦痛を与えるものです、現在私はデザインに多くのフラグメントが含まれているアプリケーションに取り組んでおり、それは携帯電話とタブレットの両方で利用可能になるでしょう、私は中道を探していますがまだ見つかりませんでした...
Nixit Patel 2012

1
正直言って、罪はないということですが、本当の答えではなく、聞きたいことだけを受け入れたと思います。スキューバの答えはGoogleによって推奨されていません。ブログの投稿で理由を説明しています。
pjco 2012

1
@pjco具体的にonItemSelected()は、アクティビティにメソッドがあることに同意しません。私の「実際の」アプリには、多くのリストとサブリストがあります。このパターンは、私のタブアクティビティにonItemSelected()各リストを処理するメソッドが必要であることを示唆しています。さらに、Phoneアクティビティには、それぞれ同じロジックが複製されている必要があります。私見では、項目選択ロジックを各フラグメントに配置する方がはるかに優れています。重複はなく、私はその方法でコードを構造化することを好みます。これがお役に立てば幸い
Richard Le Mesurier 2012

2
私は現在、このジレンマに悩まされています。フラグメントは、新しいアクティビティを起動するよりもはるかに速く読み込まれるため、単一のアクティビティアーキテクチャの実装を開始しました。私は問題に出くわしました、それは私が何かハックをすることなしにマルチフラグメント構成をサポートする良い方法を見つけることができないようであるということです。この質問を参照してください。
theblang 2014年

回答:


41

チュートリアルが非常に単純化されていることに同意します。彼らは紹介するFragmentsだけですが、提案されているパターンには同意しません。

また、アプリのロジックを多くのアクティビティ間で複製することは良い考えではないことにも同意します(WikipediaのDRY Principleを参照)。


私はActionBarSherlockFragments 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つの利点は、多くのロジックを含むタブレットアクティビティがなくなることです。つまり、メモリを節約できます。チュートリアルパターンは、より複雑なアプリで非常に大きなメインアクティビティにつながる可能性があります。いつでもそこに配置されるすべてのフラグメントのロジックを処理する必要があるためです。

全体として、多くのアクティビティを使用せざるを得ないとは考えないでください。コードを多くのフラグメントに分割し、それらを使用するときにメモリを節約する機会があると考えてください。


包括的な答えを求めるthx-私はABSデモを見てきましたが、そこには優れたコードがたくさんあると思います。代わりに、ロジックの大部分をフラグメントに移動しようとします
Richard Le Mesurier 2012

デモアプリケーションはここに移動しました:play.google.com/store/apps/...
フィリップ・E.

あなたが記述しているパターンは、元のGoogleサンプルコードからのもの だと思います:android-developers.blogspot.com/2011/02/…ActionBarSherlockは、ABSクラスを使用するようにGoogleデモコードを移植したと思います。
Dan J

17

私はあなたが正しい軌道に乗っていると思います。(そしてはい、チュートリアルは単純化しすぎています)。

タブレットレイアウトでは、単一のアクティビティを使用して、フラグメントを(複数の「ペイン」で)入れ替えることができます。電話のレイアウトでは、フラグメントごとに新しいアクティビティを使用できます。

そのようです:

ここに画像の説明を入力してください

追加の作業のように思えるかもしれませんが、電話に複数のアクティビティを使用することで、基本的なアクティビティのライフサイクルとインテントの受け渡しを可能にします。これにより、フレームワークですべてのアニメーションとバックスタックを処理することもできます。

コードを削減するには、a BaseActivityを使用し、そこから拡張できます。

したがって、ユーザーがタブレットを持っている場合は、使用するタブレットMyMultiPaneFragActivityまたはそれに類似したものを使用します。このアクティビティは、フラグメントからのコールバックを管理し、インテントを正しいフラグメント(検索インテントなど)にルーティングします。

ユーザーが電話を持っている場合は、ごくわずかなコードで通常のアクティビティを使用し、それを拡張MyBaseSingleFragActivityまたは類似のものにすることができます。これらのアクティビティは、非常に単純なコードで、5〜10行のコードになる可能性があります(それよりも少ない場合もあります)。

トリッキーな部分は、インテントのルーティングなどです。*(編集:以下を参照)。

これが推奨される方法である理由は、メモリを節約し、複雑さと結合を減らすためです。フラグメントを交換する場合FragmentManager、はバックスタック用にそのフラグメントへの参照を維持します。また、ユーザーにとって何が「実行」されるべきかを簡素化します。このセットアップでは、フラグメントのビューとレイアウトおよびロジックをアクティビティのライフサイクルから切り離します。このようにして、フラグメントは、単一のアクティビティ内、別のフラグメント(2ペイン)とともに、または3ペインアクティビティ内などに存在できます。

*定期的なインテントルーティングを使用する利点の1つは、バックスタックのどこからでもアクティビティを明示的に起動できることです。1つの例は、検索結果の場合です。(MySearchResults.class)。

詳しくはこちらをご覧ください:

http://android-developers.blogspot.com/2011/09/preparing-for-handsets.html

各フラグメントは個別のアクティビティ全体で適切に機能する必要があるため、少し先行する作業になる可能性がありますが、通常は効果があります。つまり、さまざまなフラグメントの組み合わせを定義する代替レイアウトファイルを使用し、フラグメントコードをモジュール化し、アクションバー管理を簡素化し、システムにすべてのバックスタック作業を処理させることができます。


MySearchResultsの利点について、携帯電話やタブレットに応じて、その意図に対応する別の方法を提案する-両方のケースで応答する単一のアクティビティを使用するよりも、なぜこれが優れているのですか?タブレットでは通常のインテントルーティングはないため、タブレットの問題を解決する必要があります。そのソリューションを携帯電話でも使用してみませんか?
Richard Le Mesurier 2012

ここでの利点は、タブレットコードが複数のペインにルーティングされることを期待できることです。単一のインテントで複数のペインを変更したい場合があります。左側の検索結果など、右側の大きなペインの最初の項目の詳細が表示されます。このコードは単一のレイアウトに移植できません。
pjco 2012

フラグメントが多いときにフラグメントを切り替えても問題ないのに、フラグメントが1つしか表示されない場合は、別のフラグメントに切り替えてはいけません。
Richard Le Mesurier

意味がわかりませんが、上記のコメントを明確にするために:マルチフラグメントレイアウトで複数のフラグメントを同時に変更したい場合があります。これは、あなたがいない再利用希望単一のフラグメントレイアウトであること、2つの断片を変更するコードが必要です
pjco

どういたしまして:)回答が役に立ったと思う場合は、
賛成投票

6

ここから取られた同じに関するレトマイヤーの答えであり、このビデオUdacityのAndroid基礎コース

アプリをさまざまなアクティビティに分割した方がよい理由はいくつかあります。

  • 単一のモノリシックアクティビティがあると、コードが複雑になり、読み取り、テスト、保守が困難になります。
  • インテントフィルターの作成と管理がはるかに困難になります。
  • 独立したコンポーネントを密結合するリスクを高めます。
  • 1つのアクティビティに機密情報と安全に共有できる情報の両方が含まれている場合、セキュリティリスクが発生する可能性が高くなります。

目安としては、コンテキストが変化するたびに新しいアクティビティを作成することをお勧めします。たとえば、別の種類のデータを表示したり、データの表示から入力に切り替えたりしています。


興味深いことに、ビデオのタイトルは「なぜフラグメントのみを使用しないのか」です
Richard Le Mesurier

それは良いアプローチであり、単一のアクティビティ、複数のフラグメントに関する多くの問題に直面しています...おそらく本当の
経験

4

この方法の1つの問題は、メインのタブレットアクティビティと個別の電話アクティビティで多くのロジックを複製することです。

マスター/ディテールパターンでは、2つのアクティビティがあります。1つは大きな画面に両方のフラグメントを示し、小さな画面には「マスター」フラグメントのみを示します。もう1つは、小さな画面で「詳細」フラグメントを示しています。

詳細ロジックは詳細フラグメントで結び付ける必要があります。したがって、アクティビティ間の詳細ロジックに関連するコードの重複はありません。詳細アクティビティは詳細フラグメントを表示するだけで、おそらくIntentエクストラからデータを渡すだけです。

また、ActionBarSherlockについて私が読んだのは、アクティビティではなくフラグメントで最もうまく機能するようです(しかし、まだ操作していません)。

ActionBarSherlockは純粋にネイティブアクションバーのバックポートであるため、ActionBarSherlockはネイティブアクションバーよりもフラグメントに関係することはありません。


単一の活動のアイデアについてどう思いますか?
theblang 2014年

@mattblang:正しいナビゲーションが得られれば問題ありません。
CommonsWare 2014年

1
同じフラグメントで新しいアクティビティを起動するよりもフラグメントを置き換える方がはるかに速いため、単一のアクティビティアーキテクチャにリファクタリングしてみました。私は同じように、しかし、あまりにも多くの思わぬ障害に実行していますように私は感じて、この。オンラインで見つけたほとんどの例、特にマスター/ディテールのようなマルチフラグメント構成では、単一のアクティビティを使用しません。だから私は少しジレンマに陥っています。
theblang 2014年

0

「電話アプリを多数のアクティビティに分割する理由はありますか?」の最初の質問を参照してください。- はい。利用可能なスペースが減るだけで、タブレットは開発者により多くのスペースを提供し、開発者は1つの画面により多くを配置できます。Androidは、アクティビティが画面を提供できることを教えてくれます。したがって、タブレットの1つの大きな画面でできることは、すべてのフラグメントを表示するのに十分なスペースがないため、電話の複数の画面に分散する必要があるかもしれません。


1文目-「アクティビティは、ユーザーが何かを行うために操作できる画面提供するアプリケーションコンポーネントです。」元のステートメントにエラーがあります。「別の画面です」と表示する
つもり
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.