将 windowTranslucentStatus 与 CollapsingToolbarLayout 结合使用
Using windowTranslucentStatus with CollapsingToolbarLayout
我正在尝试获得与 google 播放中看到的效果类似的效果。
我有下面的布局来显示一个透明的工具栏,它后面有一个图像。当用户滚动时,当图像视图滚出屏幕时,它会产生视差效果。工具栏 returns 每当用户向上滚动时,图像视图仅在用户到达列表顶部时返回。
这一切都很好。
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/background_material_dark">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
app:statusBarScrim="#09b"
app:contentScrim="#09f">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/location_banner"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7"
/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:layout_collapseMode="pin"
android:fitsSystemWindows="true"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
问题
当我将 windowTranslucentStatus 设置为 true 时。
视图中的内容向上移动到状态栏下方,但 CollapsingToolbarLayout 的内容向上移动状态栏高度的两倍(CollapsingToolbarLayout 保持正确的高度)。
这意味着图像顶部的部分内容被切掉了,操作栏现在显示在状态栏下方,而不是下方。作为一个副作用,现在在 CollapsingToolbarLayout 的底部有一个与状态栏高度相同的填充
这是没有 windowTranslucentStatus 时的样子。这里一切正常
windowTranslucentStatus 设置为 true
用户从列表的底部向上滚动(不是在顶部)
我有同样的问题,但我知道一件事。
如果你想在普通工具栏上有一个透明的状态栏,你需要在顶部添加一个 16dp 的内边距。
将 fitsSystemWindows 添加到布局并设置为 true。
更新
抱歉我的回答不完整。
您应该像下面的代码一样将 fitsSystemWindows="true" 添加到布局 xml 中。
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/background_material_dark"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
app:statusBarScrim="#09b"
app:contentScrim="#09f"
android:fitsSystemWindows="true">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/location_banner"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7"
android:fitsSystemWindows="true"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:layout_collapseMode="pin"
android:fitsSystemWindows="true"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
一旦状态栏透明并且activity可以自由使用,工具栏就会被推到顶部占据那个space。要解决此问题,您需要手动将工具栏移动到原始位置。
将以下标签添加到 "android.support.v7.Widget.Toolbar" 视图:
android:layout_height="48dp" // Whatever the height of the toolbar you want
android:layout_marginTop="-48dp" // Negative of the height of the toolbar
设计库现已更新。我猜上面发布的问题是一个错误。
如果将设计库更新到最新版本,则不会再出现此问题。
我现在已经删除了所有 fitsSystemWindows="true" 除了 ImageView(因为它需要显示在状态栏下)。
我还删除了工具栏中的减号填充。
这是我 21+
的主题
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:textColorPrimary">@android:color/white</item>
</style>
现在一切正常
实现这一目标的最佳方式就像 Stimsoni 所说
添加 android:fitsSystemWindows="true" 到 CoordinatorLayout、AppBarLayout 和 ImageView
<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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBar"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="256dp"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"
android:alpha="0.75"
android:src="@drawable/foo"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>...
扩展 CoordinatorLayout
并在构造函数中调用 setOnApplyWindowInsetsListener
以重置插入值。这是代码:
public class CustomCoordinatorLayout extends CoordinatorLayout {
public CustomCoordinatorLayout(Context context) {
super(context);
init();
}
public CustomCoordinatorLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
WindowInsets replaced = windowInsets.replaceSystemWindowInsets(0, 0, 0, 0);
return replaced;
}
});
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
只需在 Styles.XML(v21)
中更改状态栏的颜色
<item name="android:statusBarColor">@android:color/transparent</item>
或删除上面的行,因为 XML 它工作完美。
我正在尝试获得与 google 播放中看到的效果类似的效果。
我有下面的布局来显示一个透明的工具栏,它后面有一个图像。当用户滚动时,当图像视图滚出屏幕时,它会产生视差效果。工具栏 returns 每当用户向上滚动时,图像视图仅在用户到达列表顶部时返回。
这一切都很好。
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/background_material_dark">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
app:statusBarScrim="#09b"
app:contentScrim="#09f">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/location_banner"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7"
/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:layout_collapseMode="pin"
android:fitsSystemWindows="true"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
问题
当我将 windowTranslucentStatus 设置为 true 时。 视图中的内容向上移动到状态栏下方,但 CollapsingToolbarLayout 的内容向上移动状态栏高度的两倍(CollapsingToolbarLayout 保持正确的高度)。
这意味着图像顶部的部分内容被切掉了,操作栏现在显示在状态栏下方,而不是下方。作为一个副作用,现在在 CollapsingToolbarLayout 的底部有一个与状态栏高度相同的填充
这是没有 windowTranslucentStatus 时的样子。这里一切正常
windowTranslucentStatus 设置为 true
用户从列表的底部向上滚动(不是在顶部)
我有同样的问题,但我知道一件事。
如果你想在普通工具栏上有一个透明的状态栏,你需要在顶部添加一个 16dp 的内边距。
将 fitsSystemWindows 添加到布局并设置为 true。
更新
抱歉我的回答不完整。 您应该像下面的代码一样将 fitsSystemWindows="true" 添加到布局 xml 中。
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/background_material_dark"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
app:statusBarScrim="#09b"
app:contentScrim="#09f"
android:fitsSystemWindows="true">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/location_banner"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7"
android:fitsSystemWindows="true"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:layout_collapseMode="pin"
android:fitsSystemWindows="true"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
一旦状态栏透明并且activity可以自由使用,工具栏就会被推到顶部占据那个space。要解决此问题,您需要手动将工具栏移动到原始位置。
将以下标签添加到 "android.support.v7.Widget.Toolbar" 视图:
android:layout_height="48dp" // Whatever the height of the toolbar you want
android:layout_marginTop="-48dp" // Negative of the height of the toolbar
设计库现已更新。我猜上面发布的问题是一个错误。
如果将设计库更新到最新版本,则不会再出现此问题。
我现在已经删除了所有 fitsSystemWindows="true" 除了 ImageView(因为它需要显示在状态栏下)。
我还删除了工具栏中的减号填充。
这是我 21+
的主题<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:textColorPrimary">@android:color/white</item>
</style>
现在一切正常
实现这一目标的最佳方式就像 Stimsoni 所说
添加 android:fitsSystemWindows="true" 到 CoordinatorLayout、AppBarLayout 和 ImageView
<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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBar"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="256dp"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"
android:alpha="0.75"
android:src="@drawable/foo"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>...
扩展 CoordinatorLayout
并在构造函数中调用 setOnApplyWindowInsetsListener
以重置插入值。这是代码:
public class CustomCoordinatorLayout extends CoordinatorLayout {
public CustomCoordinatorLayout(Context context) {
super(context);
init();
}
public CustomCoordinatorLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
WindowInsets replaced = windowInsets.replaceSystemWindowInsets(0, 0, 0, 0);
return replaced;
}
});
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
只需在 Styles.XML(v21)
中更改状态栏的颜色<item name="android:statusBarColor">@android:color/transparent</item>
或删除上面的行,因为 XML 它工作完美。