11

TL; DR: Spotify iPadアプリに似た深いナビゲーションを備えたマルチペインアプリはAndroidでどのように表示され、機能する必要がありますか?また、これを実装する方法は?

ロングバージョン: ユーザーがアイテムのリストを表示し、これらのアイテムをさらに深く掘り下げることができるアプリに取り組んでいます。これらのアイテム詳細ページは、関連アイテムのリストを再び開くことができ、そのリストには詳細ページなどがあります。電話アプリとして、これらは次のように見え、相互にリンクする可能性のある個別のアクティビティになります。 ユーザーは[概要]の[アイテム#2]をクリックして詳細ページを表示し、[ ここでは、物事のリストが開いており、ユーザーは表示することを選択します

モックアップでは、ユーザーは最初の概要を確認し、最初のリストから「アイテム#2」を選択します。新しいアクティビティが開き、アイテム#2の詳細が表示されます。ここで、彼はアイテム#2に関連するもののリストを表示することを選択します。3番目の図の新しくオープンエンドのアクティビティはこのリストを示しており、1つをクリックするとこのリストの詳細が開きます。彼は好きなだけコンテンツに深く入り込むことができます。

これは、通常のAndroidアクティビティで非常にうまく機能します。私はアプリをタブレットに導入することに取り組んでおり、これを最適に実装する方法を考えています。計画は、同じコンセプトでマルチペインレイアウトを作成することです。これは、iPad Spotifyアプリの動作と非常によく似ています(タブレット固有のレイアウトを作成した後、Androidにこれをどのようにもたらすかを見るのは興味深いでしょう)。

タブレットレイアウトでは、アイテムまたはリスト名をクリックするたびに、対応する子アイテムが右からアニメーション化される新しいペインとして開きます。上記の例と同じワークフローは次のようになります。

初期のマルチペインタブレットレイアウト ユーザーがアイテム#2を選択すると、右側のペインにアイテムの詳細ページが開きます。 詳細ページで、ユーザーは Thing#3をクリックすると、右側のペインにThingの詳細が表示されます。

このナビゲーションパターンを最適に実装する方法がわかりません。Gmailのようにナビゲーションの深さが制限されているマルチペインアプリは、すべてのフラグメントを含む静的なViewGroup(LinearLayoutで問題ありません)を使用して構築できます。ナビゲーションを深く掘り下げると、右側の次のコンテナーのコンテンツが置き換えられ、これにアニメーション化されます(を参照)。SOでのこれのCommonWares実装)。

これは、カスタムViewGroupが進むべき道であることを示唆しています。サブページ(つまり、「リスト」)を表示する必要がある場合は、フラグメントを含む画面の半分の幅の新しい子をViewGroupに作成し、表示されている領域をスクロールして、操作したばかりのペインを表示します。と新しい子が表示されます。これをFragmentTransactionに正しくリンクして、バックスタックが正しく機能するようにするには、次のようになります。

View newPane = container.addChild();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(newPane, new ListOfThingsFragment(2));
ft.remove(paneOnRight, fragmentOnRight);
ft.commit();
container.animateToRight();

FragmentTransaction内でアニメーションを実行する方法がわかりません。

フィードバックを歓迎します。私の雇用主は、私たちが開発するオープンソーシングフレームワークに関して一般的に好意的です。したがって、これがより幅広い関心事であり、再利用可能なソリューションを思い付くことができれば、それを共有できれば幸いです。

4

3 に答える 3

6

私はいくらかの調査時間を持ち、この質問に対する解決策を思いつきました (あなたが質問する前から、長い間解決策を見たいと思っていた質問です)。いくつかの IP 境界があるため、コード全体を実際に表示することはできませんが、このアニメーションが機能する主要な部分をここに示します。

setCustomAnimations2 つの重要なツールがあります。LayoutTransition はい、私ができる限り、それを機能させるにはセット アニメーションを分離する必要があります。

それでは、いくつかのコードに取り掛かりましょう。XML を水平方向の LinearLayout で定義し、次の行を含めるようにします。

android:animateLayoutChanges="true"

LayoutTransitionこれにより、レイアウトにとどまっているフラグメント/ビューを変換し、レイアウトに含まれているか、レイアウトから削除されているフラグメント/ビューをアルファ化 (インまたはアウト)する標準が自動生成されます。試してみる。

したがって、このレイアウトがインフレートされた後、この LayoutTransition をキャプチャして、必要に応じてそれをトリックします。

LayoutTransition lt = myLinearLayout.getLayoutTransition();
lt.setAnimator(LayoutTransition.APPEARING, null);
lt.setAnimator(LayoutTransition.DISAPPEARING, null);
lt.setStartDelay(LayoutTransition.CHANGE_APPEARING, 0);
lt.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);

そのコードを使用して、アルファ アニメーションを削除し、トランジションの遅延を取り除きます (すべての翻訳を同時に開始するため)。

そして今、それを機能させるための単純なフラグメント トランザクションがいくつかあります。初期化中に、そのレイアウトを膨張させ、いくつかのフラグメントを配置します。

setContentView(R.layout.main); // the layout with that Linear Layout
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.main, frag1, FRAG_1_TAG); // it's good to have tags so you can find them later
ft.add(R.id.main, frag2, FRAG_2_TAG);
ft.add(R.id.main, frag3, FRAG_3_TAG);
ft.hide(frag3);
ft.commit();

トランザクションは簡単です:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.push_left_in, R.anim.push_left_out, R.anim.push_right_in, R.anim.push_right_out);
Fragment left = getFragmentManager().findFragmentByTag(FRAG_1_TAG);
Fragment right = getFragmentManager().findFragmentByTag(FRAG_3_TAG);

ft.hide(left);
ft.show(right);

ft.addToBackStack(null);
ft.commit();

最後のメモ:

より深いナビゲーションを行うFragmentTransactionsには、LinearLayout や左側のフラグメントにフラグメントを追加するhideだけdetachです。

また、フラグメントを線形レイアウトで機能させるには、実行時に LinearLayout.LayoutParams.weight を設定することが重要です。次のコードに似たものがフラグメント ビューに適用されます。

((LinearLayout.LayoutParams) view.getLayoutParams()).weight = 1;

電話でも機能させるには、共通の複数画面サポートパターンを適用するだけです。

最後の注意点として、デバイスのローテーション中のレイアウト ステータスの適切な管理には注意してください。これは、すべてがシステムによって自動的に処理されるわけではないためです。

ハッピーコーディング!

于 2013-01-04T10:20:40.880 に答える
4

アプリで同じ問題が発生しました。私たちが自分たちに与えた制約:

  • ペインの動的な数
  • 各ペインは異なるサイズにすることができます
  • ペイン内のフラグメントは、向きを変更しても正しく保持される必要があります。

これらの制約に照らして、PanesLayoutと呼ばれる新しいレイアウトを作成しました。あなたはここでそれをチェックすることができます:

https://github.com/cricklet/Android-PanesLibrary

基本的に、動的なサイズのペインをいくつでも簡単に追加し、それらのペインにフラグメントをアタッチできます。お役に立てば幸いです。:)

于 2013-02-19T16:47:39.427 に答える
2

アニメーション部分に対する部分的な回答: FragmentTransaction を使用してアニメーションを実行できます。

ft.setCustomAnimations(android.R.anim.slide_in_left, 
    android.R.anim.slide_out_right);

更新: フラグメント アニメーションに関する Reto Meier 自身からのこの回答を参照してください: https://stackoverflow.com/a/4819665/1007169

于 2012-12-27T11:21:43.927 に答える