美文网首页Android学习实用适配
Android 沉浸式状态栏(渐变) 适配异形屏和全面屏的

Android 沉浸式状态栏(渐变) 适配异形屏和全面屏的

作者: 总会颠沛流离 | 来源:发表于2019-07-22 11:56 被阅读154次
    image

    分析

    //沉浸式状态栏
    api 'com.jaeger.statusbarutil:library:1.5.1'

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

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

    实现思路

    1. 设置状态栏的颜色为透明和让整个布局沉浸到状态栏中 head_toolbar.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    
    <android.support.design.widget.AppBarLayout
        style="@style/BaseAppBarLayoutStyle"
        android:background="@drawable/shapes"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay"
        tools:ignore="MissingConstraints">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toobar"
            style="@style/BaseToolbarStyle"
            app:popupTheme="@style/AppTheme.PopupOverlay">
    
            <TextView
                android:id="@+id/toobar_text"
                style="@style/ToolBarTitleStyle"
                android:text="标题栏" />
    
        </android.support.v7.widget.Toolbar>
    
    </android.support.design.widget.AppBarLayout>
    </LinearLayout>
    
    2:在BaseActivity 中
      @Override
    protected void onStart() {
        super.onStart();
        if (!isInitToolbar) {
            initToolbar();
        }
    }
    
    
    /**
     * 初始化toolbar<p>
     * 如果子页面不需要初始化ToolBar,请直接覆写本方法做空操作即可
     * </p>
     */
    protected void initToolbar() {
        mToolBar = findViewById(R.id.base_toolbar);
        if (null != mToolBar) {
            // 设置为透明色
            mToolBar.setBackgroundColor(0x00000000);
            // 设置全透明
            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);
            }
        }
        // 设置沉浸和状态栏的颜色为透明
        StatusBarUtil.setTranslucentForImageView(this, 0, null);
    }
    
    /**
     * 返回按钮
     * 子类通过覆写本方法返回需要设置的返回按钮,也可以直接在xml中直接赋值
     * @return
     */
    protected int getNavigationIcon() {
        return R.drawable.ic_chevron_left_write_24dp;
    }
    
    /**
     * 获取状态栏高度
     *
     * @param context context
     * @return 状态栏高度
     */
    private int getStatusBarHeight(Context context) {
        // 获得状态栏高度
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        return context.getResources().getDimensionPixelSize(resourceId);
    }
    
    
    /**
     * 返回按钮点击
     */
    protected void onNavigationOnClickListener() {
        finish();
    
    }
    

    看上去我们已经完美,接下来我们就尝试直接将背景颜色更改为 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>
    

    3:value中

    base.dimens.xml
     <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
    <!--文字大小 start-->
    <dimen name="display4">112sp</dimen>
    <dimen name="display3">56sp</dimen>
    <dimen name="display2">45sp</dimen>
    <dimen name="display1">34sp</dimen>
    <!--头条-->
    <dimen name="headerline">24sp</dimen>
    <!--标题-->
    <dimen name="title">20sp</dimen>
    <!--次要标题-->
    <dimen name="subhead">16sp</dimen>
    <!--主体内容-->
    <dimen name="body2">14sp</dimen>
    <dimen name="body1">13sp</dimen>
    <dimen name="caption">12sp</dimen>
    <dimen name="menu">12sp</dimen>
    <dimen name="button">12sp</dimen>
    <dimen name="title_right">14sp</dimen>
    <!--文字大小 end-->
    
    <!--标题栏样式 start-->
    <dimen name="toolbar_height">44dp</dimen>
    <dimen name="toolbar_left_margin">14dp</dimen>
    <!--标题栏样式 end-->
    
    </resources>
    

    config_style

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
    
    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
    
    <style name="AppThemeMain" parent="AppTheme">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowIsTranslucent">false</item>
    </style>
    
    <!--标题栏 导航文字颜色-->
    <color name="ToolbarNavTextColor">#fff</color>
    <!--标题栏 标题文字颜色-->
    <color name="ToolbarTitleTextColor">#fff</color>
    <!--标题栏 阴影线颜色-->
    <color name="ToolbarLineColor">#eeeeee</color>
    <!--导航文字大小-->
    <dimen name="ToolbarNavTextSize">15sp</dimen>
    <!--标题文字大小-->
    <dimen name="ToolbarTitleTextSize">18sp</dimen>
    <!--标题栏的高度-->
    <dimen name="AppBarLayoutHeight">48dp</dimen>
    <!--导航文字距离左边的边距-->
    <dimen name="ToolbarNavTextMarginLeft">12dp</dimen>
    
    
    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
    
    <style name="BaseAppBarLayoutStyle">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:theme">@style/AppTheme.AppBarOverlay</item>
        <!--这里设置 标题栏的颜色-->
        <item name="android:id">@id/base_appbar</item>
    </style>
    
    
    <!--标题栏的样式-->
    <style name="BaseToolbarStyle" parent="Widget.AppCompat.Toolbar">
        <!--内容距离开始 边距-->
        <item name="contentInsetStart">8dp</item>
        <!--内容距离 导航按钮 边距-->
        <item name="contentInsetStartWithNavigation">8dp</item>
        <!--使自定义view可以贴左右的边,多数版本的系统不要下面两句也可以,但少量版本必须加下面的两句-->
        <item name="android:paddingLeft">8dp</item>
        <!--右内边距-->
        <item name="android:paddingRight">0dp</item>
        <!--最小高度-->
        <item name="android:minHeight">?actionBarSize</item>
        <!--高度-->
        <item name="android:layout_height">@dimen/toolbar_height</item>
        <!--id-->
        <item name="android:id">@id/base_toolbar</item>
        <!--宽度-->
        <item name="android:layout_width">match_parent</item>
        <item name="actionMenuTextColor">#000</item>
    </style>
    
    <style name="ToolBarTitleStyle">
        <!--标题栏 标题样式-->
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textColor">@color/white</item>
        <item name="android:layout_gravity">center</item>
        <item name="android:background">@null</item>
        <item name="android:textSize">13sp</item>
        <item name="android:layout_centerInParent">true</item>
        <item name="android:id">@id/tv_toolbar_title</item>
    </style>
    
    <!--标题栏返回按钮样式-->
    <style name="ToolbarNavigationButtonStyle" parent="Widget.AppCompat.Toolbar.Button.Navigation">
        <item name="android:minWidth">16dp</item>
    </style>
    
    <style name="ToolBarNavTextStyle">
        <!--标题栏返回文字样式-->
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">match_parent</item>
        <!--返回按钮和返回文字之间的间隔-->
        <item name="android:layout_marginLeft">2dp</item>
        <item name="android:gravity">center</item>
        <item name="android:layout_alignParentBottom">true</item>
        <item name="android:textColor">@color/ToolbarNavTextColor</item>
        <item name="android:textSize">@dimen/ToolbarNavTextSize</item>
        <item name="android:id">@id/toolbar_nav_text</item>
    </style>
    
    <style name="AppTheme.ToolbarHeight">
        <!--修改了标题栏默认样式的样式
        修改了返回按钮的边距
        -->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="toolbarNavigationButtonStyle">@style/ToolbarNavigationButtonStyle</item>
        <!--NavigationIcon的宽度-->
        <item name="toolbarStyle">@style/BaseToolbarStyle</item>
        <!--解决PopuWindow重叠-->
        <item name="android:windowIsTranslucent">false</item>
    </style>
    </resources>
    

    4:最后一步

    image.png
    提示:可能会报资源重复的错误,删除掉默认的style 中的就可以了 需要源码的可以联系我

    相关文章

      网友评论

        本文标题:Android 沉浸式状态栏(渐变) 适配异形屏和全面屏的

        本文链接:https://www.haomeiwen.com/subject/kvmilctx.html