Toolbar滑动变色

本文介绍在安卓应用中实现Toolbar随界面滑动变色的两种方法:一种使用scrollview或RecyclerView,另一种结合coordinatelayout和appbarlayout。通过透明状态栏和颜色透明度调整,提升用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现在很多app都有toolbar随着界面的滑动而进行变色的效果,无论是交互还是效果感觉都比较不错,现进行下尝试

效果图:

toolbar变色一般界面都是采用沉浸式,即透明状态栏,这里说两种实现方式:

1. toolbar随scrollview、RecyclerView滑动进行变色

这种布局相对不受限制,自由度更高一些

2. 采用coordinatelayout+appbarlayout+CollapsingToolbarLayout+toolbar+RecyclerView

toolbar跟随appbarlayout视差滚动进行颜色的变化,效果上更顺滑些,但是感觉布局有些受限制

 

首先是沉浸式打造:

activity theme:

<style name="AppTheme.NoActionBar">
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
<!--<item name="android:windowTranslucentStatus">true</item>-->
</style>

在界面设置:

//透明状态栏
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)

就可以实现状态栏透明了,这里状态栏透明后,原先属于状态栏的高度也没有了,布局里边要注意下,可以在原先的布局中加上状态栏的高度,这样看起来就正常了。

先说第一种:

布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent">


    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:layout_width="match_parent"
                                                           android:layout_height="wrap_content">

        <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent"
                                                   android:layout_height="match_parent" android:id="@+id/recycler"/>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>


    <androidx.appcompat.widget.Toolbar android:layout_width="match_parent"
                                       android:layout_height="76dp"
                                       app:contentInsetStart="0dp"
                                       android:id="@+id/toolbar"
    >
        <TextView android:layout_width="match_parent" android:layout_height="match_parent"
                  android:paddingTop="20dp" android:text="List" android:textStyle="bold"
                  android:id="@+id/tv_title"
        />
    </androidx.appcompat.widget.Toolbar>

</RelativeLayout>

利用后设置的布局会遮挡前边的布局,然后toolbar跟随RecyclerView变色就能做出效果了。

界面:

/**
 * 沉浸式状态栏+toolbar变色实现二
 */
class ToolbarActivity2 : AppCompatActivity() {

    private val mAdapter by lazy {
        BaseAdapter(DataUtil.getStringData())
    }

    private val manager by lazy {
        LinearLayoutManager(this@ToolbarActivity2)
    }

    private var header_hight: Int = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_toolbar2)

        //透明状态栏
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)


        val header = layoutInflater.inflate(R.layout.item_header, null)
        header.run {
            mAdapter.addHeaderView(header)
            post {
                header_hight = this.height / 2
            }
        }

        recycler.run {
            layoutManager = manager
            adapter = mAdapter
            addOnScrollListener(scrollListener)
        }


    }

    private var scrollY = 0

    private val scrollListener = object : RecyclerView.OnScrollListener() {
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            scrollY += dy
            if (scrollY <= 0) {
//                toolbar.setBackgroundResource(android.R.color.transparent)
//                tv_title.setText("")
            } else if (scrollY > 0 && scrollY < header_hight) {
                val fraction = scrollY * 1f / header_hight
                toolbar.setBackgroundColor(changeAlpha(resources.getColor(R.color.colorPrimary), fraction))
                tv_title.setTextColor(changeAlpha(resources.getColor(android.R.color.white), fraction))
            } else if (scrollY >= header_hight) {
                toolbar.setBackgroundResource(R.color.colorPrimary)
                tv_title.setText("List")
            }
        }
    }

    /**
     * 根据百分比修改颜色透明度
     */
    fun changeAlpha(color: Int, fraction: Float): Int {
        val red = Color.red(color)
        val green = Color.green(color)
        val blue = Color.blue(color)
        val alpha = (Color.alpha(color) * fraction).toInt()
        return Color.argb(alpha, red, green, blue)
    }
}

代码比较清晰,不再赘述。

方式二:

布局:

<?xml version="1.0" encoding="utf-8"?>

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                                     xmlns:app="http://schemas.android.com/apk/res-auto"
                                                     android:orientation="vertical"
                                                     android:layout_width="match_parent"
                                                     android:layout_height="match_parent">


    <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent"
                                                     android:layout_height="250dp" android:id="@+id/appbar">


        <com.google.android.material.appbar.CollapsingToolbarLayout android:layout_width="match_parent"
                                                                    android:layout_height="match_parent"
                                                                    app:layout_scrollFlags="scroll|exitUntilCollapsed">


            <ImageView android:layout_width="match_parent" android:layout_height="match_parent"
                       android:background="@drawable/banner1" app:layout_collapseMode="parallax"/>

            <androidx.appcompat.widget.Toolbar android:layout_width="match_parent"
                                               android:layout_height="76dp" android:id="@+id/toolbar"
                                               app:layout_collapseMode="pin" app:contentInsetStart="0dp"
                                               android:background="@color/colorPrimary">
                <TextView android:layout_width="match_parent" android:layout_height="match_parent"
                          android:paddingTop="20dp" android:text="爱花草" android:gravity="center"
                          android:textColor="@android:color/white"
                />
            </androidx.appcompat.widget.Toolbar>


        </com.google.android.material.appbar.CollapsingToolbarLayout>


    </com.google.android.material.appbar.AppBarLayout>


    <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent"
                                               android:layout_height="match_parent" android:id="@+id/recycler"
                                               app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

界面:

class ToolbarActivity : AppCompatActivity() {
    private val mAdapter by lazy {
        SimpleAdapter(this, DataUtil.getStringData())
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_toolbar)

        //透明状态栏
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)

        appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, i ->
            val fraction = Math.abs(i * 1.0f) / appBarLayout.totalScrollRange
            val color = changeAlpha(resources.getColor(R.color.colorPrimary), fraction)
            toolbar.setBackgroundColor(color)
        })

        recycler.run {
            layoutManager = LinearLayoutManager(this@ToolbarActivity)
            adapter = mAdapter
            mAdapter.setOnItemClickListener(object : SimpleAdapter.OnItemClickListener {
                override fun onItemClick(v: View, position: Int) {
                    Toast.makeText(this@ToolbarActivity, "pos:${position}", Toast.LENGTH_SHORT).show()
                }
            })
        }
    }

    /**
     * 根据百分比修改颜色透明度
     */
    fun changeAlpha(color: Int, fraction: Float): Int {
        val red = Color.red(color)
        val green = Color.green(color)
        val blue = Color.blue(color)
        val alpha = (Color.alpha(color) * fraction).toInt()
        return Color.argb(alpha, red, green, blue)
    }
}

 以上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值