我改进了Android Studio的导航抽屉活动项目模板,该模板使用工具栏, v7.app.ActionBarDrawerToggle 和 NavigationView 代替NavigationDrawerFragment(和layout / fragment_navigation_drawer.xml)。
完美的工作。然后,我走得更远。我的导航抽屉项目采用沉浸式粘性(全屏)模式。
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
View decorationView = getWindow().getDecorView();
decorationView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
...
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerToggle = new ActionBarDrawerToggle(
this,
drawerLayout,
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
) {
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
drawerLayout.setDrawerListener(drawerToggle);
navigationView = (NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(this);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.onOptionsItemSelected(item)) {
return true;
}
...
}
问题已经出现。从状态栏(在顶部)和导航栏(在底部)导出的NavigationView上重叠阴影效果的波段保持不变。
我怎样摆脱它们?
我查看了Android的v7.app.ActionBarDrawerToggle或NavigationView的来源,但是徒劳无功。
<小时/>
感谢@ lcw_gg的建议,我完全摆脱了状态栏的阴影(导航栏的阴影仍然存在)。这是在布局xml中设置android:windowFullscreen
属性true
。
但我想在Java代码中这样做。我找到了一种方法,可能它等同于xml方式:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
通过这样做,您不再需要将这两个标志 - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
和View.SYSTEM_UI_FLAG_FULLSCREEN
- 设置为decorationView
。
尽管如此,我还是找不到摆脱导航栏阴影的方法。我正在等待解决方案。
答案 0 :(得分:16)
最后,我做到了。
解决方案是将 FLAG_LAYOUT_NO_LIMITS
与 FLAG_FULLSCREEN
一起使用到android.view.Window
对象。
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
这完全摆脱了两个阴影。
lcw_gg&#39的评论是操纵android.view.Window
的非常有用的线索。特别感谢他。
答案 1 :(得分:2)
接受答案有问题。设置标志FLAG_FULL_SCREEN
和FLAG_LAYOUT_NO_LIMITS
将使窗口的内嵌为0,并且内容可能位于系统UI的后面。
之所以会成功,是因为NavigationView
是ScrimInsetsFrameLayout
的子类,当窗口插入全部为0时,会监听onApplyWindowInsets
和View.setWillNotDraw
为true。
您只需要在NavigationView
中添加以下内容:
app:insetForeground="@null"
答案 2 :(得分:1)
对于那些与上述问题相同但希望始终显示系统状态栏的人(因此不使用WindowManager.LayoutParams.FLAG_FULLSCREEN
),还需要做一些额外的工作来防止奇怪的内容蔓延到棒棒糖上的状态栏。当我测试它时,我没有注意到kitkat的问题。
我正在使用两个导航抽屉(左和右),奇怪的是只有左边一个投影底部的阴影。一旦应用WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
,如接受的答案中所示,阴影消失,但随后状态栏下的内容蠕动以及状态栏顶部的导航抽屉绘图;一直到设备挡板。
要解决此问题,您必须在v21 styles.xml中覆盖您的主题以包含:
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:statusBarColor">@color/colorPrimaryDark</item>
这会将内容移回状态栏下方,同时也会阻止导航抽屉在状态栏上方绘制。
除了我的v21样式中的上述条目外,我的活动代码如下所示:
// Fixes bottom navbar shadows from appearing on side navigation drawers
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
WindowManager.LayoutParams attributes = getWindow().getAttributes();
attributes.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
getWindow().setAttributes(attributes);
}
答案 3 :(得分:0)
感谢 hata ,我已经通过合并他的原始代码成功完全隐藏了系统UI:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
View decorationView = getWindow().getDecorView();
decorationView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
在致电onCreate
之前在我的活动的inflate
中添加了解决方案代码:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
很明显,标志WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
是使我的设备(API 21)上的全屏正常工作所缺少的部分