Android 滑动改变标题/栏导航栏颜色、透明度

Android 滑动改变标题/栏导航栏颜色、透明度。

Android 滚动改变标题/栏导航栏颜色、透明度

初始状态下,标题栏是透明的,随着滑动屏幕,标题颜色发生改变,而且icon和文字的颜色也发生了相应的变化,有个渐变的转化过程

android 改变标题栏/状态的颜色、透明度


思路梳理

 1. 监听ScrollView 的滑动

 2. Toolbar等标题栏(导航栏)背景颜色/透明度的变化

 3. 文字及icon图片的颜色变化

技能知识:ScrollView 滑动监听

谷歌之前并没有给我们提供外置的ScrollView滑动监听,但是在API 23上已经有了,这里我们先不管。所以在API 23 之前需要我们自己去处理ScrollView 的滑动监听。

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() 方法后面执行的
     * <p>
     * 用来这是左边边距的。默认是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滚动改变标题栏颜色透明度

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您好!针对您的问题,您可以使用 Android 中的 Toolbar 控件来实现滑动渐变标题栏。 具体实现步骤如下: 1. 在布局文件中添加 Toolbar 控件,并设置其高度为 wrap_content。 2. 在代码中通过 findViewById 获取 Toolbar 对象,并调用 setSupportActionBar 方法将其设置为当前 Activity 的 ActionBar。 3. 在 Activity 的 onCreate 方法中,通过 getSupportActionBar().setDisplayHomeAsUpEnabled(true) 设置标题栏左侧显示返回按钮。 4. 在滑动时,通过监听 RecyclerView 的滚动事件,动态改变标题栏的背景颜色透明度,实现滑动渐变效果。 5. 在 onScrollStateChanged 方法中,根据当前滚动状态判断是否需要执行动画效果。 下面是一个简单的示例代码: ```java // 获取 Toolbar 对象 Toolbar toolbar = findViewById(R.id.toolbar); // 将 Toolbar 设置为当前 Activity 的 ActionBar setSupportActionBar(toolbar); // 显示返回按钮 getSupportActionBar().setDisplayHomeAsUpEnabled(true); // 监听 RecyclerView 的滚动事件 recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE) { // 滑动停止时执行动画效果 animateToolbarColor(0xFF0000FF, 0x00000000); } } @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); // 获取当前 RecyclerView 的滚动位置 int scrollY = recyclerView.computeVerticalScrollOffset(); // 计算标题栏透明度 int alpha = Math.min(255, scrollY * 2); // 执行动画效果 animateToolbarColor(Color.argb(alpha, 0xFF, 0x00, 0x00), Color.argb(0, 0x00, 0x00, 0x00)); } }); // 改变标题栏背景颜色透明度的动画效果 private void animateToolbarColor(int fromColor, int toColor) { ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), fromColor, toColor); colorAnimation.setDuration(250); colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animator) { toolbar.setBackgroundColor((int) animator.getAnimatedValue()); } }); colorAnimation.start(); } ``` 希望这个示例能够对您有所帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值