繁体   English   中英

带有阴影效果的滚动透明工具栏

[英]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>

解决方案

我设法得到了我想要的! 我认为它更容易获得,但是,我写了我的解决方案,以防它有用并且如果有人想改进它!

首先,谷歌应用消息的方式来做到这一点。

当用户不滚动时,工具栏高度为 0。 在此处输入图片说明

当用户滚动时,工具栏高度改变并且整个工具栏和状态栏(注意状态栏)是透明的!

在此处输入图片说明

我的看起来怎么样? 在此处输入图片说明

在此处输入图片说明

让我们在 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM