Android 滑动改变标题/栏导航栏颜色、透明度
16lz
2021-01-23
Android 滑动改变标题/栏导航栏颜色、透明度。
初始状态下,标题栏是透明的,随着滑动屏幕,标题颜色发生改变,而且icon和文字的颜色也发生了相应的变化,有个渐变的转化过程
思路梳理
1. 监听ScrollView 的滑动 2. Toolbar等标题栏(导航栏)背景颜色/透明度的变化 3. 文字及icon图片的颜色变化
技能知识:ScrollView 滑动监听
谷歌之前并没有给我们提供外置的ScrollView滑动监听,但是在API 23上已经有了,这里我们先不管。所以在API 23 之前需要我们自己去处理ScrollView 的滑动监听。
1、自定义一个监听ScrollView滑动的接口
public interface OnScrollChangedListener { /** * 滑动监听 * * @param scrollView ScrollView控件 * @param x x轴坐标 * @param y y轴坐标 * @param oldx 上一个x轴坐标 * @param oldy 上一个y轴坐标 */ void onScrollChanged(ScrollView scrollView, int x, int y, int oldx, int oldy); }
2、写一个类继承ScrollView,重写其onScrollChanged()方法,通过接口的方式来监听ScrollView滑动改变。
@Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (mOnScrollChangedListener != null) { mOnScrollChangedListener.onScrollChanged(this, x, y, oldx, oldy); } }
技能知识:setAlpha 修改背景颜色透明度
滑动屏幕,从初始状态到最终状态,可以发现只是背景颜色的透明图发生了变化,而并不是整个标题栏/导航栏的透明度变化。通过设置导航栏/标题栏背景drawable的alpha 来实现渐变
Drawable drawable = view.getBackground(); if (drawable != null) { drawable.setAlpha(alpha); }
技能知识:PorterDuffColorFilter 过滤图片颜色
颜色过滤,这里不对PorterDuffColorFilter 这个类做详细介绍,大概知道它可以用来过滤图片颜色就ok!Drawable 和ImageView 都有setColorFilter 这个方法。
PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP); drawable.setColorFilter(colorFilter); imageView.setColorFilter(colorFilter);
代码实现
其实主要代码并不多,就是OnScrollChangedListener 接口中实现的那些。
package com.skx.tomike.activity;import android.graphics.Color;import android.graphics.PorterDuff;import android.graphics.PorterDuffColorFilter;import android.graphics.drawable.Drawable;import android.os.Bundle;import android.support.v4.content.ContextCompat;import android.support.v7.app.ActionBar;import android.support.v7.widget.Toolbar;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.ImageView;import android.widget.ScrollView;import com.skx.tomike.R;import com.skx.tomike.customview.TranslucentScrollView;import com.skx.tomike.util.DpPxSpTool;import com.skx.tomike.util.ToastTool;public class ToolBarActivity extends SkxBaseActivity { private ImageView iv_mainImage; private TranslucentScrollView mScrollView; private Toolbar mToolbar; private Drawable overflowIcon; private Drawable searchIcon; private Drawable shareIcon; private Drawable backIcon; int mAlpha = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tool_bar); initializeView(); refreshView(); installListener(); } @Override public void initializeView() { super.initializeView(); mScrollView = (TranslucentScrollView) findViewById(R.id.toolbar_scrollView); iv_mainImage = (ImageView) findViewById(R.id.toolbar_mainImage); mToolbar = (Toolbar) findViewById(R.id.my_toolbar); } @Override public void refreshView() { super.refreshView(); mToolbar.setTitle("Tomike");//设置主标题 mToolbar.setTitleTextColor(Color.argb(255, 255, 255, 255)); // ToolBar右侧隐藏按钮 overflowIcon = mToolbar.getOverflowIcon(); setSupportActionBar(mToolbar); ActionBar ab = getSupportActionBar(); // 返回键按钮 backIcon = ContextCompat.getDrawable(mContext, R.drawable.icon_back); ab.setHomeAsUpIndicator(backIcon); // 设置这个后会导致 myToolbar.setNavigationIcon(R.mipmap.ic_launcher) 失效,不显示; ab.setDisplayHomeAsUpEnabled(true); } @Override public void installListener() { super.installListener(); mScrollView.setOnScrollChangedListener(new TranslucentScrollView.OnScrollChangedListener() { @Override public void onScrollChanged(ScrollView scrollView, int x, int y, int oldx, int oldy) { /** ScrollView 滚动动态改变标题栏 */ // 滑动的最小距离(自行定义,you happy jiu ok) int minHeight = 50; // 滑动的最大距离(自行定义,you happy jiu ok) int maxHeight = iv_mainImage.getHeight() - DpPxSpTool.dip2px(mContext, minHeight); // 滑动距离小于定义得最小距离 if (scrollView.getScrollY() <= minHeight) { mAlpha = 0; } // 滑动距离大于定义得最大距离 else if (scrollView.getScrollY() > maxHeight) { mAlpha = 255; } // 滑动距离处于最小和最大距离之间 else { // (滑动距离 - 开始变化距离):最大限制距离 = mAlpha :255 mAlpha = (scrollView.getScrollY() - minHeight) * 255 / (maxHeight - minHeight); } // 初始状态 标题栏/导航栏透明等 if (mAlpha <= 0) { setViewBackgroundAlpha(mToolbar, 0); mToolbar.setTitleTextColor(Color.argb(255, 255, 255, 255)); iconColorFilter(Color.parseColor("#ffffff")); } // 终止状态:标题栏/导航栏 不在进行变化 else if (mAlpha >= 255) { setViewBackgroundAlpha(mToolbar, 255); mToolbar.setTitleTextColor(Color.argb(255, 0, 0, 0)); iconColorFilter(Color.parseColor("#000000")); } // 变化中状态:标题栏/导航栏随ScrollView 的滑动而产生相应变化 else { setViewBackgroundAlpha(mToolbar, mAlpha); mToolbar.setTitleTextColor(Color.argb(255, 255 - mAlpha, 255 - mAlpha, 255 - mAlpha)); iconColorFilter(Color.argb(255, 255 - mAlpha, 255 - mAlpha, 255 - mAlpha)); } } @Override public void onScrollStop(boolean isScrollStop) { } }); } /** * 标题栏/导航栏icon 颜色改变 * * @param color */ private void iconColorFilter(int color) { PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP); overflowIcon.setColorFilter(colorFilter); shareIcon.setColorFilter(colorFilter); searchIcon.setColorFilter(colorFilter); backIcon.setColorFilter(colorFilter); } /** * 注意: 这个方法是在onStart() 方法后面执行的 * * 用来这是左边边距的。默认是16dp * app:contentInsetLeft="0dp" * app:contentInsetStart="0dp" */
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_tool_bar, menu); MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem shareItem = menu.findItem(R.id.action_share); // 搜索按钮Drawable searchIcon = searchItem.getIcon(); // 分享按钮Drawable shareIcon = shareItem.getIcon(); initNavigationBar(); return true; } /** * 初始化导航栏 * 包括: * 导航栏背景透明度, * 操作按钮颜色透明度, * 标题文字颜色等。 */ private void initNavigationBar() { setViewBackgroundAlpha(mToolbar, 0); iconColorFilter(Color.parseColor("#ffffff")); } /** * 设置View的背景透明度 * * @param view * @param alpha */ public void setViewBackgroundAlpha(View view, int alpha) { if (view == null) return; Drawable drawable = view.getBackground(); if (drawable != null) { drawable.setAlpha(alpha); } }
遗留问题
东西呢,比较简单。但是我发现个问题,不点击按钮的情况下一切正常。但是如果了ToolBar的右边隐藏按钮,就会出现问题,回头再研究下是怎么个情况。效果如下图
更多相关文章
- 在Android上实现图像颜色过滤与反转
- Android 中的ListView选中项的背景颜色怎么设置?
- Android中自定义SeekBar的背景颜色,进度条颜色,以及滑块的图片
- 在Android使用XML文件控制按钮文字在各种状态下的颜色
- 自定义ListView的Item项在pressed或selected等状态时的颜色
- android textview改变部分文字的颜色