簡體   English   中英

片段或活動中帶有工具欄的協調器布局

[英]Coordinator Layout with Toolbar in Fragments or Activity

有了新的設計庫,有幾個新的布局可以改變工具欄的行為方式,如果開發人員願意的話。 由於不同的片段具有不同的行為和目標,例如帶有顯示重要照片的折疊工具欄的圖庫片段,或者沒有滾動視圖的片段,不需要 appbarlayout 來隱藏工具欄,在活動中使用單個工具欄可以證明很難。

那么有了這個,我應該將工具欄移動到每個片段嗎? 如果是這樣,我必須在每次顯示片段時設置 supportActionBar,並且還必須引用片段中的活動,這使片段的獨立性質無效。 如果我將工具欄單獨留在 Activity 中,我必須為每個片段中的每種行為定義多個布局。 最好的方法是什么?

至於我,在每個片段中都有應用欄和工具欄聽起來太奇怪了。 所以我選擇在活動中使用帶有工具欄的單個應用欄。

要使用 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"每個片段中,您必須覆蓋onAttachonDetach方法,這將改變您的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 將不會折疊 appbar 等,並將允許片段布局為全高。

這是我的解決方案

<!-- 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>

這是一個非常好的問題:需要像ActionBar一樣運行的Toolbar應該保存在Activity還是Fragment 在搜索了不同的問題和文檔后,我找不到涵蓋所有情況的解決方案。 因此,這實際上取決於您要走的路。

情況一:Toolbar必須被ActionBar替換

如果工具欄必須表現得像一個普通的 ActionBar(或者如果不時顯示最多 1 個片段),我認為最好/最簡單的方法是使用帶有自己的工具欄的傳統Activities並將您的片段放在那里。 這樣您就不必擔心何時必須顯示哪個工具欄。

也可以從 Fragments 更改 ActionBar (-behaviour),但我不建議這樣做,因為這會迫使您跟蹤哪個 Fragment 何時更改了 ActionBar。 我什至不知道是否可以多次設置 ActionBar。

案例 2:每個 Fragment 都應該有自己的(部分)Toolbar

您還可以選擇將不同的獨立工具欄放在不同的 Fragment 中,並使用它們自己的操作。 通過這種方式,您可以顯示彼此相鄰的不同 Fragment - 每個片段在其工具欄中都有自己的操作 - 並建議它是 1 個工具欄(可能類似於 Gmail 應用程序,盡管我不確定)。 然而,這意味着您必須自己膨脹這些工具欄,但這一定不是很困難。

我希望這有助於做出選擇。

(對不起,如果我犯了任何(語言)錯誤)

這就是導航文檔所說的

當應用欄的布局對於您的應用中的每個目的地都相似時,將頂部應用欄添加到您的活動中效果很好。 但是,如果您的頂部應用欄在不同目的地之間發生了重大變化,那么請考慮從您的 Activity 中移除頂部應用欄並在每個目的地片段中定義它。

實際上,使用NavigationUI設置Toolbar非常容易,並且此解決方案不需要 Fragment 對其父級有任何了解。 例如:

<!-- my_fragment.xml -->
<androidx.constraintlayout.widget.ConstraintLayout ...>

  <com.google.android.material.appbar.MaterialToolbar
    android:id="@+id/toolbar"
    ... />

</androidx.constraintlayout.widget.ConstraintLayout>
class MyFragment : Fragment() {
  ...

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val navController = findNavController()
    binding.toolbar.setupWithNavController(navController)
  }
}

您可以在此處找到完整的 GitHub 示例。 還有一個可能感興趣的相關問題Is setSupportActionbar 不再需要?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM