Translucent/Transparent 状态栏 + CoordinatorLayout + 工具栏 + Fragment
Translucent/Transparent status bar + CoordinatorLayout + Toolbar + Fragment
我有以下设置:
- 我正在使用 AppCompat
- MainActivity,包含片段和工具栏,向下滚动时隐藏
Fragment
与 RecyclerView
- 所有适合屏幕的视图在 xml 布局中都有相应的
android:fitsSystemWindows="true"
问题是,在这种情况下我无法使状态栏透明。我所做的如下:
- 创建 activity 并调用 setContent
然后我尝试调整 activity 以编程方式获得半透明工具栏,如下所示:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void themeNavAndStatusBar(Activity activity)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
return;
Window w = activity.getWindow();
w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
w.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
w.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
w.setNavigationBarColor(activity.getResources().getColor(android.R.color.transparent));
w.setStatusBarColor(activity.getResources().getColor(android.R.color.transparent));
}
用片段
替换activity(@+id/frame_container
)中的占位符
在这种情况下,状态栏是纯色的,它下面没有绘制视图...为什么?
我想要的
我想要一个工具栏,它在屏幕上滚动并完全隐藏,而此工具栏下方的内容应适合屏幕并绘制在透明导航栏后面。
布局
这是我的主要内容 activity:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/clMain"
android:fitsSystemWindows="true"
android:background="?attr/main_background_color"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:fitsSystemWindows="true"
android:background="@null"
app:elevation="0dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="?actionBarThemeStyle"
app:popupTheme="?actionBarPopupThemeStyle"
app:layout_scrollFlags="scroll|enterAlways">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/ivToolbarDataSource"
android:layout_gravity="center_vertical"
android:layout_marginRight="2dp"
android:layout_width="24dp"
android:layout_height="24dp" />
<TextView
android:id="@+id/tvToolbarTitle"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:theme="?actionBarThemeStyle"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="@+id/tvToolbarSubTitle"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle"
android:theme="?actionBarThemeStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<!-- BUG: -->
<View
android:layout_width="fill_parent"
android:layout_height="1dp"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/frame_container"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="32dp"
android:src="@drawable/ic_local_offer_white_24dp"
app:backgroundTint="?attr/colorPrimary"
app:borderWidth="0dp"
app:fabSize="normal"
app:rippleColor="?attr/colorPrimaryDark"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior="com.test.classes.ScrollAwareFABBehavior"/>
</android.support.design.widget.CoordinatorLayout>
这是我的片段,将放在主activity:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/srlImages"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvImages"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:id="@+id/tvEmpty"
android:gravity="center"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
编辑 - 截图
我使用 light/dark 基本主题并手动设置所有主题(因为用户可以 select 任何颜色作为 primary/accent 颜色),所以不要介意工具栏是白色(这是默认的主题背景色和原色)。我还添加了一个黑色边框,以便您看到 activity 结束的位置...
- 第一个屏幕截图:显示工具栏,未滚动任何内容
- 第二个屏幕截图:我刚开始滚动 => 工具栏现在应该滚开
- 第三个屏幕截图:主要内容现在应该在导航栏下方滚动...
最后,为了更好的视觉效果,我当然会把toolbar和navbar做成半透明的...
编辑您的 styles.xml (v21) ,添加以下样式
<style name="AppTheme.Home" parent="AppTheme.Base">
<!-- Customize your theme here. -->
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
您可以根据自己的喜好更改父主题,但现在在您的 AndroidManifest.xml 文件中为特定 activity 声明此主题,如下所示:
<activity
android:theme="@style/AppTheme.Home"
android:name=".HomeActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
这将使您的内容在透明操作栏下可见。
现在使用以下命令将您的工具栏正确对齐到 StatusBar 下方,在您的 oncreate 中调用它:
toolbar.setPadding(0, getStatusBarHeight(), 0, 0);
使用以下方法获取状态栏高度:
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
从协调器布局标签中删除以下内容:
android:fitsSystemWindows="true"
现在要折叠或隐藏工具栏,您可以参考 this tutorial
确保您使用的是以下版本的设计支持库,因为它没有错误:
compile 'com.android.support:design:23.1.0'
tl;dr 至少将 android:fitsSystemWindows="false"
设置为根 CoordinatorLayout
和内部片段容器 @frame_container
.
这可能不是最终解决方案(即可能还有其他 fitsSystemWindows
需要更改)所以如果您有任何问题请告诉我。
为什么
说到状态栏,我觉得fitsSystemWindows
是这样的:
fitsSystemWindows="false"
: 正常绘制视图,在 状态栏下,因为您设置了 window 标志。
fitsSystemWindows="true"
:正常绘制视图,在 状态栏下,因为您设置了 window 标志,但 添加顶部填充,以便内容绘制在状态栏下方并且它们不会重叠。
其实在我看来,你看到的白色不是状态栏的颜色,而是你的CoordinatorLayout
背景。这是由于协调器上的 fitsSystemWindows="true"
:它将背景绘制到整个 window,但向内容添加了顶部填充,因此内部视图不会被状态栏覆盖。
这不是你想要的。您的内部内容 必须 被状态栏覆盖,因此您必须将 fitsSystemWindows="false"
设置为协调器(因此它不会应用顶部填充)并且可能设置为内容本身。
一旦了解了它的工作原理,就可以轻松调试并实现您正在寻找的效果。 其实不然。多年过去了,但我仍然花费数小时试图找出正确的 fitsSystemWindows 组合,因为大多数视图(至少在支持库中)以大多数不直观的方式覆盖了我上面所述的默认行为。有关如何使用它的小指南,请参阅 this post。
在阅读了您对问题的描述后,我认为 Google Photos 的样式符合您的要求。
好的,这里只是针对您的问题的一些提示。经过我的测试,它是有效的。
- 如果你想在状态栏后面显示内容,你需要添加
<item name="android:windowTranslucentStatus">true</item>
到你的
Android版本级别大于19时的样式(即KitKat)
- 如果你想在导航栏后面显示内容,你需要添加
<item name="android:windowTranslucentNavigation">true</item>
进入你的
Android版本级别大于19时的样式(即KitKat)
- 如果你想在内容向上滚动时平滑地隐藏
Toolbar
并在内容向下滚动时顺利显示 Toolbar
,你
需要将 app:layout_collapseMode="parallax"
添加到您的
Toolbar
的属性基于您当前的 codes.Of 课程,您
需要坐标 Toolbar
和 CollapsingToolbarLayout
CoordinatorLayout
和 AppBarLayout
.
对我来说,原因不是它本身不起作用,而是我使用了 Mike Penz 的 material 抽屉库,这个库确实在工具栏后面使用了全屏 + 偏移 + 自定义背景,所以我必须解决有关该特殊设置的问题...
不过我会把积分奖励给我认为最有信息量的答案...
我遇到了同样的问题,我的解决方案是将 android:fitsSystemWindows="true" 添加到 DrawerLayout
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
....
</android.support.v4.widget.DrawerLayout>
我有相关问题取决于 android:fitsSystemWindows 设置。
一旦错误:
导航栏下画了点心
一旦为真:
状态栏有 none 透明背景
解决方案非常简单...
只需添加 android:layout_marginBottom="48dp"。像这样的 CoordinatorLayout:
just to add <android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
tools:context=".MapsActivity"
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
android:layout_marginBottom="48dp">
理论上导航栏应该有固定大小“48dp”,但在未来的版本中它可能会改变(比如状态栏在 Marshmallow 中变窄 1dp),所以我不会依赖固定大小。
最好另外获得它并在 运行 时间申请。
如果你像我一样使用Google地图你可能想知道ActionBar/Toolbar尺寸和运行时间的导航栏:
在 onCreate 中使用此代码:
final TypedArray styledAttributes = MapsActivity.this.getTheme().obtainStyledAttributes(
new int[]{android.R.attr.actionBarSize});
mToolbarHeight = (int) styledAttributes.getDimension(0, 0);
styledAttributes.recycle();
// translucent bars code. Will not fire below Lollipop
// Ask NavigationBar Height
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.coordinatorLayout),
new OnApplyWindowInsetsListener() { // setContentView() must be fired already
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
statusBar = insets.getSystemWindowInsetTop(); // You may also need this value
mNavBarHeight = insets.getSystemWindowInsetBottom();
if (mMap != null)
mMap.setPadding(0, mToolbarHeight, 0, mNavBarHeight);
// else will be set in onMapReady()
SharedPreferences.Editor editor = mSharedPref.edit();
editor
.putInt(NAVBAR_HEIGHT_KEY, mNavBarHeight)
.commit(); // Save the results in flash memory and run the code just once on app first run instead of doing it every run
return insets;
}
}
);
重要的是。如果你有一些额外的层,比如抽屉等,把它们封装在 CoordinatorLayout 内部而不是外部,否则它会使内部的其他视图缩短 marginBottom
正如某些用户所说,通过设置android:fitsSystemWindows="false"
,布局重叠低于statusbar
。
我通过设置 android:fitsSystemWindows="true"
和 CoordinatorLayout
标签设置 app:statusBarBackground="@android:color/transparent"
.
解决了这个问题
我通过使状态栏透明来使工具栏具有与状态栏相同的颜色:
build.gradle
...
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
**ScrollingActivity.kt**
```kt
class ScrollingActivity : AppCompatActivity(R.layout.activity_scrolling) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setSupportActionBar(toolbar)
}
}
activity_scrolling.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"
tools:context=".ScrollingActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content"
android:background="#f00" android:fitsSystemWindows="true" android:theme="@style/AppTheme.AppBarOverlay">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin" android:text="@string/large_text" />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
styles.xml
<resources>
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>
清单
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.lb.myapplication">
<application
android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
<activity
android:name=".ScrollingActivity" android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
您应该在您的主题中添加以下代码,此代码将使状态栏透明:
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
此外,将滚动行为添加到您的顶部应用栏。以下示例显示顶部应用栏在向上滚动时消失,在向下滚动时出现:
<androidx.coordinatorlayout.widget.CoordinatorLayout
...>
<com.google.android.material.appbar.AppBarLayout
...>
<com.google.android.material.appbar.MaterialToolbar
...
app:layout_scrollFlags="scroll|enterAlways|snap"
/>
</com.google.android.material.appbar.AppBarLayout>
...
</androidx.coordinatorlayout.widget.CoordinatorLayout>
首先将此代码添加到 AppBarLayout:
app:liftOnScroll="true"
然后更新工具栏中的“应用程序:layout_scrollFlags”:
app:layout_scrollFlags="scroll|enterAlways|snap"
我很确定这会奏效。
我有以下设置:
- 我正在使用 AppCompat
- MainActivity,包含片段和工具栏,向下滚动时隐藏
Fragment
与RecyclerView
- 所有适合屏幕的视图在 xml 布局中都有相应的
android:fitsSystemWindows="true"
问题是,在这种情况下我无法使状态栏透明。我所做的如下:
- 创建 activity 并调用 setContent
然后我尝试调整 activity 以编程方式获得半透明工具栏,如下所示:
@TargetApi(Build.VERSION_CODES.LOLLIPOP) public void themeNavAndStatusBar(Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; Window w = activity.getWindow(); w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); w.setFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); w.setFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); w.setNavigationBarColor(activity.getResources().getColor(android.R.color.transparent)); w.setStatusBarColor(activity.getResources().getColor(android.R.color.transparent)); }
用片段
替换activity(
@+id/frame_container
)中的占位符
在这种情况下,状态栏是纯色的,它下面没有绘制视图...为什么?
我想要的
我想要一个工具栏,它在屏幕上滚动并完全隐藏,而此工具栏下方的内容应适合屏幕并绘制在透明导航栏后面。
布局
这是我的主要内容 activity:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/clMain"
android:fitsSystemWindows="true"
android:background="?attr/main_background_color"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:fitsSystemWindows="true"
android:background="@null"
app:elevation="0dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="?actionBarThemeStyle"
app:popupTheme="?actionBarPopupThemeStyle"
app:layout_scrollFlags="scroll|enterAlways">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/ivToolbarDataSource"
android:layout_gravity="center_vertical"
android:layout_marginRight="2dp"
android:layout_width="24dp"
android:layout_height="24dp" />
<TextView
android:id="@+id/tvToolbarTitle"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:theme="?actionBarThemeStyle"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="@+id/tvToolbarSubTitle"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle"
android:theme="?actionBarThemeStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<!-- BUG: -->
<View
android:layout_width="fill_parent"
android:layout_height="1dp"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/frame_container"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="32dp"
android:src="@drawable/ic_local_offer_white_24dp"
app:backgroundTint="?attr/colorPrimary"
app:borderWidth="0dp"
app:fabSize="normal"
app:rippleColor="?attr/colorPrimaryDark"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior="com.test.classes.ScrollAwareFABBehavior"/>
</android.support.design.widget.CoordinatorLayout>
这是我的片段,将放在主activity:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/srlImages"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvImages"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:id="@+id/tvEmpty"
android:gravity="center"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
编辑 - 截图
我使用 light/dark 基本主题并手动设置所有主题(因为用户可以 select 任何颜色作为 primary/accent 颜色),所以不要介意工具栏是白色(这是默认的主题背景色和原色)。我还添加了一个黑色边框,以便您看到 activity 结束的位置...
- 第一个屏幕截图:显示工具栏,未滚动任何内容
- 第二个屏幕截图:我刚开始滚动 => 工具栏现在应该滚开
- 第三个屏幕截图:主要内容现在应该在导航栏下方滚动...
最后,为了更好的视觉效果,我当然会把toolbar和navbar做成半透明的...
编辑您的 styles.xml (v21) ,添加以下样式
<style name="AppTheme.Home" parent="AppTheme.Base">
<!-- Customize your theme here. -->
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
您可以根据自己的喜好更改父主题,但现在在您的 AndroidManifest.xml 文件中为特定 activity 声明此主题,如下所示:
<activity
android:theme="@style/AppTheme.Home"
android:name=".HomeActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
这将使您的内容在透明操作栏下可见。
现在使用以下命令将您的工具栏正确对齐到 StatusBar 下方,在您的 oncreate 中调用它:
toolbar.setPadding(0, getStatusBarHeight(), 0, 0);
使用以下方法获取状态栏高度:
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
从协调器布局标签中删除以下内容:
android:fitsSystemWindows="true"
现在要折叠或隐藏工具栏,您可以参考 this tutorial
确保您使用的是以下版本的设计支持库,因为它没有错误:
compile 'com.android.support:design:23.1.0'
tl;dr 至少将 android:fitsSystemWindows="false"
设置为根 CoordinatorLayout
和内部片段容器 @frame_container
.
这可能不是最终解决方案(即可能还有其他 fitsSystemWindows
需要更改)所以如果您有任何问题请告诉我。
为什么
说到状态栏,我觉得fitsSystemWindows
是这样的:
fitsSystemWindows="false"
: 正常绘制视图,在 状态栏下,因为您设置了 window 标志。fitsSystemWindows="true"
:正常绘制视图,在 状态栏下,因为您设置了 window 标志,但 添加顶部填充,以便内容绘制在状态栏下方并且它们不会重叠。
其实在我看来,你看到的白色不是状态栏的颜色,而是你的CoordinatorLayout
背景。这是由于协调器上的 fitsSystemWindows="true"
:它将背景绘制到整个 window,但向内容添加了顶部填充,因此内部视图不会被状态栏覆盖。
这不是你想要的。您的内部内容 必须 被状态栏覆盖,因此您必须将 fitsSystemWindows="false"
设置为协调器(因此它不会应用顶部填充)并且可能设置为内容本身。
一旦了解了它的工作原理,就可以轻松调试并实现您正在寻找的效果。 其实不然。多年过去了,但我仍然花费数小时试图找出正确的 fitsSystemWindows 组合,因为大多数视图(至少在支持库中)以大多数不直观的方式覆盖了我上面所述的默认行为。有关如何使用它的小指南,请参阅 this post。
在阅读了您对问题的描述后,我认为 Google Photos 的样式符合您的要求。
好的,这里只是针对您的问题的一些提示。经过我的测试,它是有效的。
- 如果你想在状态栏后面显示内容,你需要添加
<item name="android:windowTranslucentStatus">true</item>
到你的 Android版本级别大于19时的样式(即KitKat) - 如果你想在导航栏后面显示内容,你需要添加
<item name="android:windowTranslucentNavigation">true</item>
进入你的 Android版本级别大于19时的样式(即KitKat) - 如果你想在内容向上滚动时平滑地隐藏
Toolbar
并在内容向下滚动时顺利显示Toolbar
,你 需要将app:layout_collapseMode="parallax"
添加到您的Toolbar
的属性基于您当前的 codes.Of 课程,您 需要坐标Toolbar
和CollapsingToolbarLayout
CoordinatorLayout
和AppBarLayout
.
对我来说,原因不是它本身不起作用,而是我使用了 Mike Penz 的 material 抽屉库,这个库确实在工具栏后面使用了全屏 + 偏移 + 自定义背景,所以我必须解决有关该特殊设置的问题...
不过我会把积分奖励给我认为最有信息量的答案...
我遇到了同样的问题,我的解决方案是将 android:fitsSystemWindows="true" 添加到 DrawerLayout
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
....
</android.support.v4.widget.DrawerLayout>
我有相关问题取决于 android:fitsSystemWindows 设置。 一旦错误: 导航栏下画了点心 一旦为真: 状态栏有 none 透明背景
解决方案非常简单... 只需添加 android:layout_marginBottom="48dp"。像这样的 CoordinatorLayout:
just to add <android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
tools:context=".MapsActivity"
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
android:layout_marginBottom="48dp">
理论上导航栏应该有固定大小“48dp”,但在未来的版本中它可能会改变(比如状态栏在 Marshmallow 中变窄 1dp),所以我不会依赖固定大小。 最好另外获得它并在 运行 时间申请。
如果你像我一样使用Google地图你可能想知道ActionBar/Toolbar尺寸和运行时间的导航栏:
在 onCreate 中使用此代码:
final TypedArray styledAttributes = MapsActivity.this.getTheme().obtainStyledAttributes(
new int[]{android.R.attr.actionBarSize});
mToolbarHeight = (int) styledAttributes.getDimension(0, 0);
styledAttributes.recycle();
// translucent bars code. Will not fire below Lollipop
// Ask NavigationBar Height
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.coordinatorLayout),
new OnApplyWindowInsetsListener() { // setContentView() must be fired already
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
statusBar = insets.getSystemWindowInsetTop(); // You may also need this value
mNavBarHeight = insets.getSystemWindowInsetBottom();
if (mMap != null)
mMap.setPadding(0, mToolbarHeight, 0, mNavBarHeight);
// else will be set in onMapReady()
SharedPreferences.Editor editor = mSharedPref.edit();
editor
.putInt(NAVBAR_HEIGHT_KEY, mNavBarHeight)
.commit(); // Save the results in flash memory and run the code just once on app first run instead of doing it every run
return insets;
}
}
);
重要的是。如果你有一些额外的层,比如抽屉等,把它们封装在 CoordinatorLayout 内部而不是外部,否则它会使内部的其他视图缩短 marginBottom
正如某些用户所说,通过设置android:fitsSystemWindows="false"
,布局重叠低于statusbar
。
我通过设置 android:fitsSystemWindows="true"
和 CoordinatorLayout
标签设置 app:statusBarBackground="@android:color/transparent"
.
我通过使状态栏透明来使工具栏具有与状态栏相同的颜色:
build.gradle
...
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
**ScrollingActivity.kt**
```kt
class ScrollingActivity : AppCompatActivity(R.layout.activity_scrolling) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setSupportActionBar(toolbar)
}
}
activity_scrolling.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"
tools:context=".ScrollingActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content"
android:background="#f00" android:fitsSystemWindows="true" android:theme="@style/AppTheme.AppBarOverlay">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin" android:text="@string/large_text" />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
styles.xml
<resources>
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>
清单
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.lb.myapplication">
<application
android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
<activity
android:name=".ScrollingActivity" android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
您应该在您的主题中添加以下代码,此代码将使状态栏透明:
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
此外,将滚动行为添加到您的顶部应用栏。以下示例显示顶部应用栏在向上滚动时消失,在向下滚动时出现:
<androidx.coordinatorlayout.widget.CoordinatorLayout
...>
<com.google.android.material.appbar.AppBarLayout
...>
<com.google.android.material.appbar.MaterialToolbar
...
app:layout_scrollFlags="scroll|enterAlways|snap"
/>
</com.google.android.material.appbar.AppBarLayout>
...
</androidx.coordinatorlayout.widget.CoordinatorLayout>
首先将此代码添加到 AppBarLayout:
app:liftOnScroll="true"
然后更新工具栏中的“应用程序:layout_scrollFlags”:
app:layout_scrollFlags="scroll|enterAlways|snap"
我很确定这会奏效。