西甲2015赛程表

对Toolbar的封装-实现渐变标题栏与沉浸适配 [复制链接]

2019-6-5 10:07
hellokenken 阅读:222 评论:1 赞:1
Tag:  

引言

看过上篇文章的演示,就应该能看到我们在滑动返回的时候,顶部的状态栏其实是没和我们的页面一起滑动的,本篇就此问题进行适配,让标题栏沉浸到状态栏中,而?#19968;?#26159;能够适配现在市面上所见的异形屏。

正文

我们要实现下面这样的一个标题栏,支持沉浸图片或者纯色,还需要提供 helper,为以后需求变更做准备。

图片描述

分析

首先来分析一下我们的布局,在默认的情况下,我们的整个屏幕分为三部分(没有考虑虚拟状态栏):状态栏、标题栏、内容区域。对于状态栏?#27492;?#25105;们只能设置颜色,而像我们上面的需求他应该是一个 Drawable 或者是一张?#23458;?#29255;。

然后在我们的实现中其实是用AppBarLayout包裹着Toolbar,我们操作的也是AppBarLayout,Toolbar保持原状。

实现思路

我们的实现思路也很简单,很多时候是没有一个思路的开头,导致无法进行。

1. 设置状态栏的颜色为?#35813;?#21644;让整个布局沉浸到状态栏中

关于状态栏操作的开源库的话,之前已经引入过StatusBarUtil,操作简单也方便,?#34892;?#36259;的可以去看一下。

我们就用 第九篇 文章中的模板, 先?#38470;?#19968;个Activity,不记得的朋友可以倒回去看看。看一下运行起来的页面吧,默认状态下什么都没有。

xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".module.example.StatusToolBarActivity">

    <android.support.design.widget.AppBarLayout
        style="@style/BaseAppBarLayoutStyle">

        <android.support.v7.widget.Toolbar
style="@style/BaseToolbarStyle"
app:popupTheme="@style/AppTheme.PopupOverlay">

<TextView
    style="@style/ToolBarNavTextStyle"
    android:text="@string/nav_call_back" />

<TextView
    style="@style/ToolBarTitleStyle"
    android:text="@string/title_activity_status_tool_bar" />
        </android.support.v7.widget.Toolbar>

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_status_tool_bar" />

</android.support.design.widget.CoordinatorLayout>

运行效果

图片描述

然后在我们的 Activity的onCreate 中加上这段代码:

// 设置沉浸和状态栏的颜色为?#35813;?StatusBarUtil.setTranslucentForImageView(this, 0, null);

看一下效果吧:

图片描述

从上图可以看出,我们的 AppBarLayout 已经沉浸到状态栏中了,而且在滑动返回的时候也显示的十分自然、符?#29616;本酢?#20294;是能看到 AppBarLayout 的位置和内容明显有点偏了,接下来就是对此进行适配。

2. 更改AppBarLayout的高度和Padding

这里适配起来也是比较简单的,因为我们是直接把 AppBarLayout 沉浸到了状态栏中,所以我们只需要在 Activity 中获取到 AppBarLayout,将 AppBarLayout 的高度更改为原本的高度+状态栏的高度,且把PaddingTo设置为状态栏的高度,将ToolBar背景颜色的更改为完全?#35813;鰨?#20854;它属性爆出不变。
关于获取 AppBarLayout ,在上一篇中我们封装过 BaseAppBarLayoutStyle ,里面有id/base_appbar。具体看代码吧。

    /**
     * 初始化标题栏
     */
    private void initBaseToolBar() {
        // 设置为?#35813;?#33394; mToolBar 已经在base中获取过了
        mToolBar.setBackgroundColor(0x00000000);
        mToolBar.setTitle("");
        // 设置全?#35813;?        mToolBar.getBackground().setAlpha(0);
        // appbar
        AppBarLayout mAppBarLayout = findViewById(R.id.base_appbar);
        // 状态栏高度 getStatusBarHeight只是一个获取高度的方法
        int statusBarHeight = getStatusBarHeight(mActivity);
        //大于 19  设置沉浸和padding
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (mAppBarLayout != null) {
    ViewGroup.MarginLayoutParams appbarLayoutParam = (ViewGroup.MarginLayoutParams) mAppBarLayout.getLayoutParams();
    // 更改高度 toolbar_height 的高度是可配置的
    appbarLayoutParam.height = (int) (getResources().getDimension(R.dimen.toolbar_height) + statusBarHeight);
    // 设置padding
    mAppBarLayout.setPadding(mAppBarLayout.getPaddingLeft(),
statusBarHeight,
mAppBarLayout.getPaddingRight(),
mAppBarLayout.getPaddingBottom());

    //重新设置回去
    mAppBarLayout.setLayoutParams(appbarLayoutParam);
}
        }
        // 设置沉浸和状态栏的颜色为?#35813;?        StatusBarUtil.setTranslucentForImageView(this, 0, null);
    }

    /**
     * 获取状态栏高度
     *
     * @param context context
     * @return 状态栏高度
     */
    private int getStatusBarHeight(Context context) {
        // 获得状态栏高度
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        return context.getResources().getDimensionPixelSize(resourceId);
    }

运行起来看看效果吧。

图片描述

看上去我们已经完美,接下来我们就尝试直接将背景颜色更改为 Drawable,为了更显眼,我特地选了一个鲜艳的颜色写了一个shape,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:angle="45"
        android:endColor="#03a4f9"
        android:startColor="#ff76D2" />
</shape>

然后为设置为AppBarLayout 的背景即可,运行起来看看吧(Gif 看上去颜色有点失真,但是实际上是很圆滑的)。

图片描述

从图中基本可以看到,基本上已经实现了最开始提的需求。其实到了这一步,我们的ToolBar已经能够满足绝大多数需求了,五彩斑斓的标题栏就此诞生~~

4. 预埋相关设置

接下来就是将初始化 ToolBar 的代码和原本 CandyBaseActivity 的合并在一起,并增加一些其它的设置,方便后续的使用。

在封装到CandyBaseActivity 需要注意以下情况:

  • 并不是每个 Activity 都需要底层初始化 ToolBar 的,类似于图片沉浸和特殊效果的页面。

  • 所以 initToolbar 这个方法应该是protected,让子类可覆写。

  • 基类不应该直接操作AppBarLayout的背景颜色,就应该像我们写的列子中一样,子类只做相关初始化,背景颜色让子类在xml中定义。

  • NavigationIcon可以让子类自己设置,在没有的情况下才使?#27809;?#31867;中定义的icon,icon的替换只需要命名为相同的名字,放到module下相同的文件夹中,最终打包将会以module为主。

CandyBaseActivity的代码量有点多,以下为主要核心代码:

/**
     * 初始化toolbar<p>
     * 如果子页面不需要初始化ToolBar,请直接覆写本方法做空操作即可
     * </p>
     */
    protected void initToolbar() {
        mToolBar = findViewById(R.id.base_toolbar);
        if (null != mToolBar) {
// 设置为?#35813;?#33394;
mToolBar.setBackgroundColor(0x00000000);
// 设置全?#35813;?mToolBar.getBackground().setAlpha(0);
// 清除标题
mToolBar.setTitle("");
setSupportActionBar(mToolBar);
// 子类中没有设置过返回按钮的情况下
if (mToolBar.getNavigationIcon() == null) {
    //设置返回按钮
    mToolBar.setNavigationIcon(getNavigationIcon());
}
mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        onNavigationOnClickListener();
    }
});
isInitToolbar = true;
//返回文字按钮
View navText = findViewById(R.id.toolbar_nav_text);
if (null != navText) {
    navText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
onNavigationOnClickListener();
        }
    });
}
        }
        // appbar
        AppBarLayout mAppBarLayout = findViewById(R.id.base_appbar);
        // 状态栏高度 getStatusBarHeight只是一个获取高度的方法
        int statusBarHeight = getStatusBarHeight(mActivity);
        //大于 19  设置沉浸和padding
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (mAppBarLayout != null) {
    ViewGroup.MarginLayoutParams appbarLayoutParam = (ViewGroup.MarginLayoutParams) mAppBarLayout.getLayoutParams();
    // 更改高度 toolbar_height 的高度是可配置的
    appbarLayoutParam.height = (int) (getResources().getDimension(R.dimen.toolbar_height) + statusBarHeight);
    // 设置padding
    mAppBarLayout.setPadding(mAppBarLayout.getPaddingLeft(),
statusBarHeight,
mAppBarLayout.getPaddingRight(),
mAppBarLayout.getPaddingBottom());

    //重新设置回去
    mAppBarLayout.setLayoutParams(appbarLayoutParam);
}
        }
        // 设置沉浸和状态栏的颜色为?#35813;?        StatusBarUtil.setTranslucentForImageView(this, 0, null);
    }

    /**
     * 返回按钮
     * 子类通过覆写本方法返回需要设置的返回按钮,?#37096;?#20197;直接在xml中直接?#25345;?     * @return
     */
    protected int getNavigationIcon() {
        return R.drawable.ic_chevron_left_write_24dp;
    }

演示一下抽取封装以后的效果:

图片描述

结束

总结

总得?#27492;擔?#23454;现并不是很困难,关键点在于实现思路。另外我们此次实现的这个ToolBar是能够适配异形屏全面屏的,不信的可以试试。

分享到:
我?#27492;?#20004;句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(1)
天明向日葵 2019-6-10 09:57
学习了
回复

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:[email protected]

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )

西甲2015赛程表 彩票开奖频道 云南十一选五开奖直播 夹猪珠电子游艺 mg电子游戏中奖 切沃维罗纳 玉皇大帝电子 城市里尔 拉佐维奇热那亚 彩票店内彩票走势图 龙卷风怎么玩