web-dev-qa-db-ja.com

フラグメントまたはアクティビティにツールバーがあるコーディネーターレイアウト

新しいデザインライブラリには、開発者が望む場合のツールバーの動作を大きく変えるいくつかの新しいレイアウトがあります。さまざまなフラグメントにはさまざまな動作と目的があるため、たとえば、重要な写真を表示する折りたたみツールバーのあるギャラリーフラグメントや、ツールバーを非表示にするためにappbarlayoutを必要とせず、アクティビティに単一のツールバーを持つことができるスクロールビューのないフラグメント難しいことがわかります。

だから、これで、ツールバーを各フラグメントに移動する必要がありますか?その場合、フラグメントを表示するたびにsupportActionBarを設定する必要があり、フラグメントの独立した性質を無効にするフラグメント内のアクティビティの参照も必要です。アクティビティのツールバーだけを残す場合、各フラグメントの動作のタイプごとに複数のレイアウトを定義する必要があります。最善のアプローチは何でしょうか?

92
mobilepotato7

私にとっては、各フラグメントにappbarとtoolbarがあるのは奇妙に聞こえます。そのため、アクティビティ中にツールバーを備えた単一のアプリバーを選択しました。

CoordinatorLayoutの問題を解決するには、デフォルトの動作をオーバーライドする各フラグメントのフラグメントを保持するFrameLayout(またはその他のレイアウト)の異なる動作を設定する必要があります。

デフォルトの動作がapp:layout_behavior="@string/appbar_scrolling_view_behavior"であると仮定しましょう

次に、fragment_activity_layout.xmlに次のようなものがあります。

<Android.support.design.widget.CoordinatorLayout
    Android:id="@+id/coordinator"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.design.widget.AppBarLayout
        Android:id="@+id/appbar"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

        <Android.support.v7.widget.Toolbar
            Android:id="@+id/dashboard_toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:theme="@style/AppTheme.Toolbar"
            app:layout_scrollFlags="scroll|enterAlways"/>
    </Android.support.design.widget.AppBarLayout>

    <FrameLayout
        Android:id="@+id/dashboard_content"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</Android.support.design.widget.CoordinatorLayout>

app:layout_behavior="@string/appbar_scrolling_view_behavior"を実装しない各フラグメントでは、onAttachの動作を変更するonDetachおよびFrameLayoutメソッドをオーバーライドする必要があります。

CoordinatorLayout.Behavior behavior;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    if(behavior != null)
        return;

    FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();

    behavior = params.getBehavior();
    params.setBehavior(null);

}

@Override
public void onDetach() {
    super.onDetach();
    if(behavior == null)
        return;

    FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();

    params.setBehavior(behavior);

    layout.setLayoutParams(params);

    behavior = null;
}

その後、CoordinatorLayoutはアプリバーなどを折りたたみません。また、フラグメントレイアウトをフルハイトにできます。

52

これが私の解決策です

<!-- Put your fragment inside a Framelayout and set the behavior for this FrameLayout -->
<FrameLayout
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <!-- Your fragment -->
    <include layout="@layout/content_main" />

</FrameLayout>

<Android.support.design.widget.AppBarLayout
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:theme="@style/AppTheme.AppBarOverlay">

    <Android.support.v7.widget.Toolbar
        Android:id="@+id/toolbar"
        Android:layout_width="match_parent"
        Android:layout_height="?attr/actionBarSize"
        Android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</Android.support.design.widget.AppBarLayout>

これは本当に良い質問です。Toolbarのように振る舞う必要があるActionBarsは、ActivityまたはFragmentに保持する必要がありますか?さまざまな質問やドキュメントを検索したところ、すべてのケースをカバーするソリューションが見つかりませんでした。したがって、実際に進むべき状況によって異なります。

ケース1:ツールバーはActionBarの代替である必要があります

ツールバーが通常のActionBarのように動作する必要がある場合(または最大1つのフラグメントが時々表示される場合)、最良/最も簡単な方法は、独自のツールバーで従来のActivitiesを使用し、そこにフラグメントを配置することです。これにより、どのツールバーを表示する必要があるかを心配する必要がなくなります。

ActionBar(-behaviour)をFragmentsから変更することも可能ですが、どのFragmentがActionBarをいつ変更したかを追跡しなければならないため、お勧めしません。 ActionBarの設定を複数回実行できるかどうかさえわかりません。

ケース2:各フラグメントには独自の(一部の)ツールバーが必要です

また、独自のアクションを使用して、さまざまなフラグメントにさまざまなスタンドアロンツールバーを配置することもできます。この方法で、異なるフラグメントを隣り合わせに表示することができます-それぞれがツールバーに独自のアクションを持ち-それが1つのツールバーであることを示唆します(おそらくGmailアプリのようですが、よくわかりません)。ただし、これは、これらのツールバーを自分で膨らませる必要があることを意味しますが、それほど難しくないはずです。

これが選択に役立つことを願っています。

((言語)間違いを犯した場合はごめんなさい)

1
Coen B