现在很多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)
}
}
以上