[英]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"
每個片段中,您必須覆蓋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 將不會折疊 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
? 在搜索了不同的問題和文檔后,我找不到涵蓋所有情況的解決方案。 因此,這實際上取決於您要走的路。
如果工具欄必須表現得像一個普通的 ActionBar(或者如果不時顯示最多 1 個片段),我認為最好/最簡單的方法是使用帶有自己的工具欄的傳統Activities
並將您的片段放在那里。 這樣您就不必擔心何時必須顯示哪個工具欄。
也可以從 Fragments 更改 ActionBar (-behaviour),但我不建議這樣做,因為這會迫使您跟蹤哪個 Fragment 何時更改了 ActionBar。 我什至不知道是否可以多次設置 ActionBar。
您還可以選擇將不同的獨立工具欄放在不同的 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.