38

フラグメントを使用して、複数の画面やレイアウトにうまく適応するアプリを作成する方法を理解しようとしています。私はいくつかの例を研究しました:

  1. Android デベロッパー ガイドのFragmentsドキュメント。
  2. Google IO アプリ
  3. ActionBar Sherlockのフラグメント サンプル。

これらはすべて、複数のActivityアプローチを提唱しています。

  • 大きな画面で、Activity複数Fragmentの sで単一を表示します。
  • 小さい画面では、 をFragment複数Activityの に分割します。

私は別のアプローチを考えました-単一のアプローチActivity

  • ActivityすべてのFragmentsを含むシングルを用意してください。
  • 画面のサイズと向きに応じて、適切なFragment(s) を表示/非表示にします ( FragmentTransaction.show()/を使用FragmentTransaction.hide()) 。

Android デベロッパー ガイドで使用されているのと同じ「ニュース記事リスト / 記事の内容」の例で説明すると、次のようになります。

  • とのNews両方を含むアクティビティを用意します。ArticleListFragmentArticleReaderFragment
  • タブでは、両方のフラグメントが常に表示されます。
  • 電話機では、ArticleReaderFragmentは最初は非表示になっています。リストから記事を選択すると、ArticleListFragmentが非表示になり、ArticleReaderFragmentが表示されます。

誰かが同様のアプローチを使用しましたか? この方法に実際的な欠点はありますか? 複数のアクティビティの方法と比較して、良い/悪いように見えますか? たとえば、フラグメントを XML で表示/非表示にすることはできません。これには使用する必要がありFragmentTransactionます。


EDIT 1: 仮説シナリオの説明

画面に一度に最大 3 つの「ペイン」を表示できるアプリを想像してみてください。さらに、考慮すべき要素は次のとおりです。

  • 電話機は一度に 1 つのペインしか表示できません (縦向き/横向きに関係なく)。
  • 7 インチのタブレットは 2 つのペインを表示でき、ポートレート モードでは垂直方向に分割され、ランドスケープ モードでは水平方向に分割されます。
  • 10 インチ以上のタブレットは、2 つのペインを縦に分割して表示できます。横向きに水平に分割された 3 つのペイン。

簡単にするために、テレビ画面については議論から除外しましょう。

さて、これをデザインに変換します:

  • Frag1、Frag2、Frag3 の 3 つのフラグメントがあります。
  • 最も単純なケースでは、3 つのフラグメントすべてが 1 つのアクティビティにあります (ActivityA と呼びましょう)。これは10インチの横型ケースです。
  • もう 1 つの「単純な」ケースは、各 Fragment が独自の Activity にある場合です。ActivityA には Frag1 が含まれています。ActivityB には Frag2 が含まれ、ActivityC には Frag3 が含まれます。

これまでのところ、Android デベロッパー ガイドに示されているニュース リーダーの例と大きく異なるものは考慮していません。唯一の大きな違いは、2 つではなく3 つのフラグメントがあることです。

今、2つの破片しか収容できない7インチのタブの場合。これはどのように機能しますか?ここでは 2 つの組み合わせが可能であることに注意してください。

  1. Frag1 と Frag2 が表示されています。
  2. Frag2 と Frag3 が表示されています。

私はこれに頭を包むことができません。このすべてを ActivityA 内で行う必要がありますか? まったく新しい ActivityD を作成するだけですか? いくつのレイアウトを作成する必要がありますか (私は約 8 つ数えました)? パーミュレーション多すぎない?

上記で提案した単一アクティビティのアプローチも、このシナリオには適していない可能性があることを認識しています-フラグメントを表示/非表示にすること自体は自明ではないためです。

レイアウトや組み合わせに圧倒されることなくこれを処理する方法について何か提案はありますか?

4

4 に答える 4

16

@テイラークラークによるこの回答はかなり有益でした。ただし、元の質問で尋ねたように、シングルアクティビティアプローチを使用した経験を実際に共有することではありませんでした。私は、Android開発者ガイドのニュースリーダーの例を変更して、単一アクティビティのアプローチを使用することに着手し、実行可能なソリューションを考え出しました。

まだわかっていないのは、このアプローチがマルチアクティビティ方式よりも好ましいユースケース(またはそのようなケースがあるかどうか)です。また、質問の編集1で説明されている3ペインのシナリオについては詳しく調べていません。

プロジェクト全体をまもなく投稿したいと思いますが、これが私がどのように取り組んだかについての簡単な概要です。

  • シングルActivity:NewsActivity
  • 2つのフラグメント:TitlesListFragmentおよびDetailsFragment
  • 両方のフラグメントは常にに存在しNewsActivityます。現在のデュアルペインネスに応じて、適切なフラグメントを表示/非表示にします。

私が遭遇したいくつかの問題:

レイアウトをデュアルペインとして指定するかどうか:

元のニュースリーダーの例では、デュアルペインレイアウトFrameLayoutにニュースの詳細を保持するためのがあります。このフレームレイアウトの存在をテストすることにより、現在デュアルペインレイアウトになっているかどうかを判断します。

ただし、私のソリューションでは、両方のフラグメントが常にすべてのレイアウトに存在します。私はこれをハックしました。これはView、IDdualPaneandroid:visibility="gone"使用して、デュアルペインにしたいレイアウトに含め、シングルペインレイアウトでこのビューを省略したものです。その後、それはの問題でした

mDualPane = findViewById(R.id.dualPane)!=null;

編集:

ダミービューを使用するよりも、デュアルペインネスを指定する方が良い方法があります。私が好むのは、ブールリソースを作成することです。たとえば、私はconfig.xml次のようにしています:

<resources>
    <bool name="dual_pane">false</bool>
</resources>

次に、などconfig.xmlのフォルダに追加のファイルを配置し、ブール値を必要に応じて調整できます。values-xlarge-landvalues-portvalues-sw600dptruefalse

次に、コードではそれはの問題ですgetResources().getBoolean(R.bool.dual_pane);

詳細フラグメントを閉じる

Activityこれは、クローズとクローズを区別する問題でしたFragment。結局、私は次のようにオーバーライドする必要がありonBackPressed()ました:

  • デュアルペインモードでは、super.onBackPressed();を呼び出すだけです。
  • シングルペインモードでは、にいる場合は;TitlesListFragmentを呼び出します。super.onBackPressed()
  • シングルペインモードでは、にいる場合はDetailsFragment、フラグメントを閉じるものとして扱います。これは、それを非表示にして表示することを意味しTitlesListFragmentます。

これは理想的ではありませんが、私が思いつくことができる最高のものです。

編集

コメントの@SherifelKhatibによる提案に基づいて、戻るボタンの押下を処理するためのはるかにクリーンな方法があります。詳細フラグメントを表示/非表示にするトランザクションであるフラグメントバックスタックに追加するだけです。そうすれば、戻るボタンを押すと、フラグメントトランザクションが逆になります。他のボタンクリックでそうしたい場合は、バックスタックを手動でポップすることもできます。

于 2012-04-16T17:48:35.413 に答える
10

通常、アプリケーションはアクティビティに分割されます。これは、それぞれがユーザーが実行できる特定の「こと」を表すためです。たとえば、電子メール アプリケーションでは、一連のアクションを次のように定義できます。

  1. メッセージのリストを表示する
  2. メッセージの詳細を表示する
  3. メールへの返信の作成。

各アクションは、単一 (またはセット) のフラグメントを示す独自のアクティビティである可能性があります。ただし、画面の不動産がある場合は、メッセージリストの表示とメッセージの詳細を「詳細ビュー」フラグメントを表示/非表示できる単一のアクティビティに結合することは理にかなっています。基本的に、フラグメントを使用すると、一度に複数の「アクティビティ」をユーザーに表示できます。

決定を下す際の考慮事項:

  1. xml で指定されたフラグメントは引数として指定できません
  2. 決定が画面の向きに基づいている場合は、いつでもリソース修飾子を使用して、フラグメントが多い/少ない別のレイアウトを指すことができます (例: layout-land-large)。
  3. フラグメントを維持できないアクティビティ
  4. Fragments は連携してユーザーに合理化されたエクスペリエンスを提供していますか?
  5. フラグメントの 1 つが永久になくなる時はありますか? もしそうなら、多分それは新しい活動の時です
  6. あなたの腸と一緒に行きます。アプリケーションがフラグメントをスワップアウトするのが「自然」である場合は、それを選択してください。頻繁に実行している場合は、別のアクティビティがより適切な解決策になる可能性があることを覚えておいてください。

私は通常、アプリケーションのタブレット バージョンには「複数のフラグメント アプローチ」を採用し、携帯電話には「アクティビティごとに 1 つのフラグメント」を採用しまし。2 番目に時間と場所がないわけではありませんが、実装がすぐに乱雑になることがわかりました。

言葉足らずな回答ですみません!おそらく、あなたの特定のユースケースについてもっと教えてもらえますか? お役に立てれば!


質問への回答 編集 1


あなたのアプリケーションプロジェクトがセットアップされると私が想像する方法は次のとおりです。

ソース ファイル:

yourapp.package.phone: NewsActivity1、NewsActivity2、NewsActivity3

yourapp.package.tablet: NewsMultipaneActivity

資力

レイアウト/

activity_news.xml- phone version, only includes Fragment1
activity_news_detail.xml- phone version, only includes Fragment2
activity_news_<something>.xml- phone version, only includes Fragment3

レイアウト大/

activity_news.xml- 7" tablet version, includes Fragment2 and an empty fragment container. Split vertically

レイアウト大地/

activity_news.xml- same as layout-large, but with the split being horizontally

layout-xlarge-land/

activity_news.xml- 10"+ tablet version, contains all three fragments split horizontally

それで、ここで何が起こりますか?

  • アプリが電話で実行されている場合は、NewsActivity1 を開始します
  • アプリがタブレットで実行されている場合は、NewsMultipaneActivity を開始します

Android は、ファイル名が同じである限り、画面のサイズと向きに基づいてレイアウトを交換します。Fragment2 は常に表示されるため、タブレット レイアウトに「ハード コード」することができます。その後、FragmentTransactions を使用して、必要に応じてコンテナー内の Fragment1 と Fragment3 を切り替えることができます。

http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResourcesを確認して、リソース修飾子を利用してさまざまな画面や向きの問題を軽減する方法を確認してください。

于 2012-04-11T04:21:11.610 に答える
1

この記事http://developer.android.com/guide/practices/tablets-and-handsets.html#Fragmentsで、 Google は次のように述べています。

「選択するアプローチは、デザインと個人的な好みによって異なります。」

「ただし、ハンドセットのデザインのフラグメントを動的に交換すると、コードがより複雑になる可能性があります。アクティビティのコードですべてのフラグメントの組み合わせを管理する必要があるためです (別のレイアウト リソースを使用してフラグメントの組み合わせを定義するのではなく)。 (通常のアクティビティ スタックがバック ナビゲーションを処理できるようにするのではなく)。"

于 2015-12-13T10:02:51.397 に答える