从片段更改工具栏
Change toolbar from fragment
我正在使用 jetpack recommended architecture, NavigationUI, and the navigation graph 编写应用程序。所以我有一个主 activity 和一个 Toolbar
、一个 BottomNavigationView
和 NavHostFragment
.
到目前为止一切正常:我需要更改 Toolbar
以使用 CollapsingToolbarLayout
并将 BottomNavigationView
隐藏在我的一个片段中。
我尝试添加一个导航侦听器(如 here 所述)以隐藏我的 Toolbar
和 BottomNavigationView
,并且在我的片段中,我膨胀了新的 Toolbar
并在 activity.
上调用 setSupportActionBar()
// in MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
if(destination.getId() == R.id.detailFragment){
bottomBar.setVisibility(View.GONE);
topBar.setVisibility(View.GONE);
}else{
bottomBar.setVisibility(View.VISIBLE);
topBar.setVisibility(View.VISIBLE);
}
});
// ...
}
public void changeToolbar(Toolbar toolbar){
getSupportActionBar().hide();
setSupportActionBar(toolbar);
}
// in DetailFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// ...
navController = NavHostFragment.findNavController(this);
AppBarConfiguration.Builder builder = new Builder(
R.id.accuracyFragment,
R.id.dataFragment,
R.id.magnetFragment,
R.id.settingsFragment);
AppBarConfiguration config = builder.build();
NavigationUI.setupWithNavController(toolbarLayout, toolbar, navController);
((MainActivity)getActivity()).changeToolbar(toolbar);
// ...
}
它几乎可以正常工作,但是:
- 当我向上导航或转到另一个片段时,
BottomNavigationView
未正确显示。好像被Toolbar
. 压下去了
- 过渡很丑陋:工具栏正在明显变化,我可以看到它在变化之前就消失了
所以问题是:是否有另一种方法 change/hide 来自片段的导航元素?如果没有,我应该创建一个新的 activity 吗?
这是一次疯狂的旅程,但我终于找到了解决办法。对于问题编号 1,这是由于 Android 管理 fitsSystemWindows
属性 传播的方式所致。为了使其正常工作,我对布局进行了一些更改。我创建了一个自定义 FitSystemWindowLinearLayout
,它只是一个 class 扩展标准 LinearLayout
并覆盖 onApplyWindowInsets
,如下所示:
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int childCount = getChildCount();
for (int index = 0; index < childCount; ++index) {
getChildAt(index).dispatchApplyWindowInsets(insets);
}
return insets;
}
我的主要 activity 现在看起来像这样:
+-- CoordinatorLayout, fitsSystemWindows=false
+-- FitSystemWindowLinearLayout, fitsSystemWindows="false"
+-- Toolbar
+-- NavHostFragment, fitsSystemWindows="false"
+-- BottomNavigationView, fitsSystemWindows="false"
对于第二个问题,即过渡丑陋,我通过向过渡添加共享元素来缓解这个问题。
总而言之,我认为使用新的 activity 更容易处理此类事情,NavigationUI 现在有点不足。
以下是一些对我有帮助的资源:
- https://medium.com/androiddevelopers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec
- Collapsing Toolbar problems with Status Bar and Bottom Bar. Fitssystemwindows="true" not working
- https://www.reddit.com/r/androiddev/comments/aryxvu/fitssystemwindows_misbehaves_with_navigation/
-https://medium.com/androiddevelopers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec
我正在使用 jetpack recommended architecture, NavigationUI, and the navigation graph 编写应用程序。所以我有一个主 activity 和一个 Toolbar
、一个 BottomNavigationView
和 NavHostFragment
.
到目前为止一切正常:我需要更改 Toolbar
以使用 CollapsingToolbarLayout
并将 BottomNavigationView
隐藏在我的一个片段中。
我尝试添加一个导航侦听器(如 here 所述)以隐藏我的 Toolbar
和 BottomNavigationView
,并且在我的片段中,我膨胀了新的 Toolbar
并在 activity.
setSupportActionBar()
// in MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
if(destination.getId() == R.id.detailFragment){
bottomBar.setVisibility(View.GONE);
topBar.setVisibility(View.GONE);
}else{
bottomBar.setVisibility(View.VISIBLE);
topBar.setVisibility(View.VISIBLE);
}
});
// ...
}
public void changeToolbar(Toolbar toolbar){
getSupportActionBar().hide();
setSupportActionBar(toolbar);
}
// in DetailFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// ...
navController = NavHostFragment.findNavController(this);
AppBarConfiguration.Builder builder = new Builder(
R.id.accuracyFragment,
R.id.dataFragment,
R.id.magnetFragment,
R.id.settingsFragment);
AppBarConfiguration config = builder.build();
NavigationUI.setupWithNavController(toolbarLayout, toolbar, navController);
((MainActivity)getActivity()).changeToolbar(toolbar);
// ...
}
它几乎可以正常工作,但是:
- 当我向上导航或转到另一个片段时,
BottomNavigationView
未正确显示。好像被Toolbar
. 压下去了
- 过渡很丑陋:工具栏正在明显变化,我可以看到它在变化之前就消失了
所以问题是:是否有另一种方法 change/hide 来自片段的导航元素?如果没有,我应该创建一个新的 activity 吗?
这是一次疯狂的旅程,但我终于找到了解决办法。对于问题编号 1,这是由于 Android 管理 fitsSystemWindows
属性 传播的方式所致。为了使其正常工作,我对布局进行了一些更改。我创建了一个自定义 FitSystemWindowLinearLayout
,它只是一个 class 扩展标准 LinearLayout
并覆盖 onApplyWindowInsets
,如下所示:
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int childCount = getChildCount();
for (int index = 0; index < childCount; ++index) {
getChildAt(index).dispatchApplyWindowInsets(insets);
}
return insets;
}
我的主要 activity 现在看起来像这样:
+-- CoordinatorLayout, fitsSystemWindows=false
+-- FitSystemWindowLinearLayout, fitsSystemWindows="false"
+-- Toolbar
+-- NavHostFragment, fitsSystemWindows="false"
+-- BottomNavigationView, fitsSystemWindows="false"
对于第二个问题,即过渡丑陋,我通过向过渡添加共享元素来缓解这个问题。
总而言之,我认为使用新的 activity 更容易处理此类事情,NavigationUI 现在有点不足。
以下是一些对我有帮助的资源:
- https://medium.com/androiddevelopers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec
- Collapsing Toolbar problems with Status Bar and Bottom Bar. Fitssystemwindows="true" not working
- https://www.reddit.com/r/androiddev/comments/aryxvu/fitssystemwindows_misbehaves_with_navigation/ -https://medium.com/androiddevelopers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec