[英]Transparent toolbar on scrolling with shadow effect
我正在尝试获得类似于 google 消息应用程序中工具栏的效果。
基本上工具栏有一个纯色,当用户滚动时,它变得透明,底部有阴影。
我设法获得了阴影效果,但无法获得透明效果。
这是我的带有工具栏的 XML AppBarLayout:
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:titleTextColor="@color/colorTextMain"
android:background="@color/colorPrimary">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
解决方案
我设法得到了我想要的! 我认为它更容易获得,但是,我写了我的解决方案,以防它有用并且如果有人想改进它!
首先,谷歌应用消息的方式来做到这一点。
当用户滚动时,工具栏高度改变并且整个工具栏和状态栏(注意状态栏)是透明的!
让我们在 ToolBar、NestedScrollView 和 LinearLayout 内部创建一个 CoordinatorLayout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:background="@color/colorPrimary">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorToolbar"
android:elevation="0dp"
app:titleTextColor="@color/colorTextMain"
android:fitsSystemWindows="true"/>
<androidx.core.widget.NestedScrollView
android:id="@+id/myScroll"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
... place page content here ...
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
现在,在您的类OnCreate方法中
// find the toolbar view inside the activity layout
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitleTextAppearance(this, R.style.FontStyle);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setTitle(getString(R.string.about));
toolbar.setElevation(1); // required or it will overlap linear layout
toolbar.setBackgroundColor(Color.TRANSPARENT); // required to delete elevation shadow
// status bar height programmatically , notches...
statusBarHeight = getStatusBarHeight();
linearLayout = findViewById(R.id.linear_layout);
linearLayout.setPadding(1,180+statusBarHeight,1,0);
ViewGroup.LayoutParams params = toolbar.getLayoutParams();
params.height = 180+statusBarHeight;
toolbar.setLayoutParams(params);
由于我们有缺口 ( :-( ),我们必须以编程方式计算状态栏高度。默认状态栏高度为 24dp。不幸的是,并非所有缺口手机都使用 24dp。 如何以编程方式计算状态栏高度
现在,无论用户是否沿页面移动,我们都需要处理工具栏的高度。 在您的类OnCreate方法中
NestedScrollView scroller = findViewById(R.id.myScroll);
scroller.setOnScrollChangeListener((NestedScrollView.OnScrollChangeListener) (v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
if (scrollY > oldScrollY) {
// when user scrolls down set toolbar elevation to 4dp
toolbar.setElevation(4);
toolbar.setBackgroundColor(getColor(R.color.colorToolbar));
}
if (scrollY < oldScrollY) {
// when user scrolls up keep toolbar elevation at 4dp
toolbar.setElevation(4);
toolbar.setBackgroundColor(getColor(R.color.colorToolbar));
}
if (scrollY == 0) {
// if user is not scrolling it means
// that he is at top of page
toolbar.setElevation(1); // required or it will overlap linear layout
toolbar.setBackgroundColor(Color.TRANSPARENT); // required to delete elevation shadow
}
});
快完成了! 这是很关键的部分! 再次在您的类OnCreate方法中
switch (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) {
case Configuration.UI_MODE_NIGHT_YES:
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getWindow().setStatusBarColor(Color.TRANSPARENT);
break;
case Configuration.UI_MODE_NIGHT_NO:
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
getWindow().setStatusBarColor(Color.TRANSPARENT);
break;
}
Configuration.UI_MODE_NIGHT_YES 和 Configuration.UI_MODE_NIGHT_NO: 是一种处理明暗主题的方法。 由于我们要将页面的所有内容都放在状态栏上,我们将无法再控制状态栏图标的颜色(可通过样式获得),因此我们需要检测是否以编程方式启用了浅色或深色主题设置状态栏图标颜色!
我认为你必须让你的 appbar 放在一个视图上。 尝试这样的事情:
<androidx.constraintlayout.widget.ConstraintLayout android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:layout_constraintTop_toTopOf="parent"
android:background="@color/transparent_color"
app:liftOnScroll="true">
<androidx.appcompat.widget.Toolbar
android:background="@color/colorPrimary"
android:fitsSystemWindows="true"
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/transparent_color"
android:minHeight="?attr/actionBarSize"
app:titleTextColor="@color/colorTextMain"/>
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:layout_height="match_parent"
android:layout_width="match_parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.