透明状态栏_状态栏透明 - CSDN
精华内容
参与话题
  • 前言: 之前我是把状态栏直接给删掉了,在style中的appTheme中添加...后来觉得删掉一点都不好,倒不如将状态栏颜色设置成透明 笔者参考了郭神的blog,真的很棒!https://blog.csdn.net/guolin_blog/article/detai...

    前言:

    之前我是把状态栏直接给删掉了,在style中的appTheme中添加这样一条:
    
    <item name="android:windowFullscreen">true</item>
    

    后来觉得删掉一点都不好,倒不如将状态栏颜色设置成透明
    笔者参考了郭神的blog,真的很棒!https://blog.csdn.net/guolin_blog/article/details/51763825

    效果图如下:
    在这里插入图片描述
    在OnCreate方法中添加这样的代码就行了

    if (Build.VERSION.SDK_INT >= 21) {
                View decorView = getWindow().getDecorView();
                int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
                decorView.setSystemUiVisibility(option);
                getWindow().setStatusBarColor(Color.TRANSPARENT);
            }
    
    

    首先需要注意,饿了么这样的效果是只有5.0及以上系统才支持,因此这里先进行了一层if判断,只有系统版本大于或等于5.0的时候才会执行下面的代码。

    接下来我们使用了SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN和SYSTEM_UI_FLAG_LAYOUT_STABLE,注意两个Flag必须要结合在一起使用,表示会让应用的主体内容占用系统状态栏的空间,最后再调用Window的setStatusBarColor()方法将状态栏设置成透明色就可以了。

    注意

    如果你没有在app主题中设置了NOActionBar,则需要把状态栏也隐藏了

    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();
    
    展开全文
  • 前言:项目中用到沉浸式状态栏,并要求随着身份的不同呈现不同的颜色。然后拜读了一些大神的文章,大致总结一下。 网上实现方式大致有两种:一种就是鸿洋大神介绍的方式,我称之为代码式;另一种是通过style+xml...

    前言:项目中用到透明式状态栏(网上也有叫沉浸式状态栏的),并要求随着身份的不同呈现不同的颜色。然后拜读了一些大神的文章,大致总结一下。
    网上实现方式大致有两种:一种就是鸿洋大神介绍的方式,我称之为代码式;另一种是通过style+xml实现,我称之为xml式。经过我自己的测试,xml式在android4.4出现navigationbar的背景色被覆盖的情况,本人暂时没有找到比较好的解决办法,故推荐采用第一种方式,即代码式。
    实现步骤:

    1、4.4之后加入windowTranslucentStatus的属性之后,可以用到状态栏的区域。由于5.0提供了setStatusBarColor去设置状态栏颜色,但是这个方法不能在主题中设置windowTranslucentStatus属性。

    故可以在oncreate中添加如下代码:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
           getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
     }

    2、根据第一点中分析,需要用到鸿洋大神写的方法StatusBarCompat。传送门

    /**
     * Created by zhy on 15/9/21.
     */
    public class StatusBarCompat
    {
        private static final int INVALID_VAL = -1;
        private static final int COLOR_DEFAULT = Color.parseColor("#20000000");
    
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public static void compat(Activity activity, int statusColor)
        {
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            {
                if (statusColor != INVALID_VAL)
                {
                    activity.getWindow().setStatusBarColor(statusColor);
                }
                return;
            }
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
            {
                int color = COLOR_DEFAULT;
                ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
                if (statusColor != INVALID_VAL)
                {
                    color = statusColor;
                }
                View statusBarView = new View(activity);
                ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        getStatusBarHeight(activity));
                statusBarView.setBackgroundColor(color);
                contentView.addView(statusBarView, lp);
            }
    
        }
    
        public static void compat(Activity activity)
        {
            compat(activity, INVALID_VAL);
        }
    
    
        public static int getStatusBarHeight(Context context)
        {
            int result = 0;
            int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0)
            {
                result = context.getResources().getDimensionPixelSize(resourceId);
            }
            return result;
        }
    }

    3、以上两点还需要设置setFitsSystemWindows=true的属性,才能保证页面达到预想效果。代码如下:

    ViewGroup contentFrameLayout = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
    View parentView = contentFrameLayout.getChildAt(0);
    if (parentView != null && Build.VERSION.SDK_INT >= 14) {
        parentView.setFitsSystemWindows(true);
    }

    4、说明:如果项目中要求整体设计统一,可以在BaseActivity中进行设置。如果仅仅是部分activity中有此需求,可以在响应的activity中调用即可。当然前提是项目采用的NoActionBar的主题。

    源码:选择statusbar Module可以查看源码

    参考博文:
    张鸿洋:Android 沉浸式状态栏攻略 让你的状态栏变色吧
    Android沉浸式状态栏(透明状态栏)最佳实现

    展开全文
  • 在我做 Android 开发之前,我就发现有些 App 的状态栏和导航栏有透明效果,或者是沉浸式效果,比如说酷安的客户端,是像这个样子的 酷安客户端 虽然只是简单的改变,但相对于传统的上下两个黑条来说,视觉效果...

    背景

    在我做 Android 开发之前,我就发现有些 App 的状态栏和导航栏有透明效果,或者是沉浸式效果,比如说酷安的客户端,是像这个样子的


    酷安客户端

    虽然只是简单的改变,但相对于传统的上下两个黑条来说,视觉效果会美观很多,我当时挺纠结很多主流应用没有这种效果,还特意安装了一个 xposed 框架的模块来强制实现沉浸式状态栏和导航栏,不过貌似那个模块会影响性能,从那时我就决定,如果将来我做 Android 开发,一定会让我开发的应用都使用这种效果,如今终于实现啦!

    开源库

    经过对大量应用的观察,我发现这种透明状态栏和导航栏或者叫沉浸式状态栏和导航栏的效果主要有以下几种:
    1、自定义颜色的状态栏和导航栏;
    2、半透明的状态栏和导航栏;
    3、完全透明的状态栏和导航栏(其实就是第二种的极限状态,我更喜欢 叫这种为沉浸式状态栏和导航栏);
    4、隐藏状态栏和导航栏。

    效果分别如下:


    自定义颜色

    半透明

    完全透明

    隐藏

    事实上,在 github 上也有不少关于这方面的开源项目,不过这些开源项目大多只是针对状态栏实现了透明或者沉浸式的效果,而对下方的导航栏并没有做相应的处理,于是我自己写了一个针对状态栏和导航栏都实现透明或者沉浸式的效果的开源库,地址如下:

    UltimateBar

    这里要特别说明一下,状态栏和导航栏透明是在 Android 4.4 开始支持的,但是 Android 4.4 的实现原理和 Android 5.0 以上的实现原理并不一样,这就导致如果在 Android 5.0 以上如果使用 Android 4.4 的实现方法会出现显示效果不一致的问题,我写的这个库分别对 Android 4.4 和 Android5.0 以上做了处理,使它在不同的系统版本下显示效果达到高度统一,使用这个库,首先需要添加依赖:

    compile 'org.zackratos:ultimatebar:1.0.3'

    接下来对上面四种情况分别作介绍。

    自定义颜色的状态栏和导航栏

    要设置自定义颜色的状态栏和导航栏只需要在 onCreate 方法中调用如下代码:

    UltimateBar ultimateBar = new UltimateBar(this);
    ultimateBar.setColorBar(ContextCompat.getColor(this, R.color.DeepSkyBlue));

    那么他的内部是怎么实现的呢,查看源码可以发现,内部源码是这样的:

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public void setColorBar(@ColorInt int color, int alpha) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            int alphaColor = alpha == 0 ? color : calculateColor(color, alpha);
            window.setStatusBarColor(alphaColor);
            window.setNavigationBarColor(alphaColor);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            int alphaColor = alpha == 0 ? color : calculateColor(color, alpha);
            ViewGroup decorView = (ViewGroup) window.getDecorView();
            decorView.addView(createStatusBarView(activity, alphaColor));
            if (navigationBarExist(activity)) {
                decorView.addView(createNavBarView(activity, alphaColor));
                window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            }
            setRootView(activity, true);
        }
    }
    
    
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public void setColorBar(@ColorInt int color) {
        setColorBar(color, 0);
    }

    我们可以看到第一个方法里面传入了两个参数,第一个参数是自定义的颜色值,第二个参数是颜色深度值,最小为 0,最大为 255,当深度值为 0 时,状态栏和导航栏的颜色就是第一个参数传入的颜色值,即为第二个方法中的情况;当深度值不为 0 时,会根据深度值计算得到最终的颜色值,然后设置到状态栏和导航栏上面。

    正如前面所说,这里分别针对 Android 4.4 和 Android 5.0 以上做了不同处理,首先来看 Android 5.0 以上的情况,事实上 Android 5.0 以上的实现非常简单,因为 Android 5.0 以上可以直接设置状态栏和导航栏的颜色,所以只需要先得到最终的颜色值,然后调用 setStatusBarColor 和 setNavigationBarColor 方法进行设置就好了。然后 Android 4.4 稍微麻烦一点,首先必须要添加 FLAG_TRANSLUCENT_STATUS 这个 flag 来把状态栏设置为透明,然后再在状态栏上面添加一个 view 来保证状态栏的颜色,然后再调用 navigationBarExist 方法来判断当前手机是否存在导航栏,如果存在,对导航栏做同样的处理,最后必须调用 setRootView 方法,这个方法是干嘛的呢,看一下它的代码:

    private void setRootView(Activity activity, boolean fit) {
        ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);
        for (int i = 0, count = parent.getChildCount(); i < count; i++) {
            View childView = parent.getChildAt(i);
            if (childView instanceof ViewGroup) {
                childView.setFitsSystemWindows(fit);
                ((ViewGroup)childView).setClipToPadding(fit);
            }
        }
    }

    可以看到,这个方法是用来设置布局的子 view 的 fitsSystemWindows 参数的,相当于在布局中添加 android:fitsSystemWindows="true",如果不调用这个方法,就会导致布局中的内容覆盖到状态栏和导航栏上面了。

    半透明的状态栏和导航栏

    半透明状态栏和导航栏的使用方法也非常简单,只要在 onCreate 方法中调用以下代码:

    UltimateBar ultimateBar = new UltimateBar(this);
    ultimateBar.setTransparentBar(Color.BLUE, 50);

    同样的看一下它的内部实现,如下:

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public void setTransparentBar(@ColorInt int color, int alpha) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            View decorView = window.getDecorView();
            int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
            decorView.setSystemUiVisibility(option);
    
            int finalColor = alpha == 0 ? Color.TRANSPARENT :
                    Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
    
            window.setNavigationBarColor(finalColor);
            window.setStatusBarColor(finalColor);
    
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            ViewGroup decorView = (ViewGroup) window.getDecorView();
            int finalColor = alpha == 0 ? Color.TRANSPARENT :
                    Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
            decorView.addView(createStatusBarView(activity, finalColor));
            if (navigationBarExist(activity)) {
                window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
                decorView.addView(createNavBarView(activity, finalColor));
            }
        }
    
    }

    两个参数分别表示颜色和透明度,透明度最小为 0,最大为 255,对于 Android 5.0 及以上,需要先添加 SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,SYSTEM_UI_FLAG_LAYOUT_STABLE 三个 flag,以保证布局的内容可以覆盖到状态栏和导航栏上面,然后同样的调用 setStatusBarColor 和 setNavigationBarColor 方法来设置状态栏和导航栏颜色,不过这里的颜色都是经过计算的半透明的颜色,对于 Android 4.4,跟之前的自定义颜色一样,首先需要添加 FLAG_TRANSLUCENT_STATUS 这个 flag 保证状态栏透明,然后再在状态栏上添加一个半透明的 view,然后调用 navigationBarExist 方法判断导航栏是否存在,如果存在,也做相同的处理,这里要注意,因为半透明状态栏和导航栏需要布局内容覆盖到状态栏和导航栏上面的效果,所以在这里不能调用 setRootView 方法。

    完全透明的状态栏和导航栏

    其实完全透明的状态栏和导航栏就是半透明的状态栏和导航栏中当透明度为 0 的情况,只需在 onCreate 方法中调用如下方法:

    UltimateBar ultimateBar = new UltimateBar(this);
    ultimateBar.setImmersionBar();

    查看它的内部实现可以发现它是这么调用的:

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public void setImmersionBar() {
        setTransparentBar(Color.TRANSPARENT, 0);
    }

    就是半透明状态栏和导航栏的特殊情况,不做过多介绍了。

    隐藏状态栏和导航栏

    这种情况比较常见了,一般玩游戏,看视频就是这种效果,这种效果的实现有点特殊,必须重写 Activity 的 onWindowFocusChanged 方法,如下:

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            UltimateBar ultimateBar = new UltimateBar(this);
            ultimateBar.setHintBar();
        }
    }

    它的内部实现也比较简单,如下:

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public void setHintBar() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            View decorView = activity.getWindow().getDecorView();
            decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        }
    }

    就是添加几个 flag,这是固定写法,也不做过多介绍了。

    针对 DrawerLayout 的实现

    还有一种特殊情况,就是对于 DrawerLayout,上面的方法会出现一些问题,达不到想要的效果,这里针对 DrawerLayout 做了特殊处理,一般来说,对于 DrawerLayout 只要实现自定义颜色的状态栏和导航栏效果就好了,其他情况就不用考虑了,可以在 onCrate 调用如下代码:

    UltimateBar ultimateBar = new UltimateBar(this);
    ultimateBar.setColorBarForDrawer(ContextCompat.getColor(this, R.color.DeepSkyBlue));

    但是这样其实还是不够的,还必须要在布局文件中在 DawerLayout 的子 view 的主界面添加 android:fitsSystemWindows="true",就像这样:

    <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            android:orientation="vertical">
        </LinearLayout>
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/SpringGreen"
            android:layout_gravity="left"/>
    
    </android.support.v4.widget.DrawerLayout>

    注意,这里是在 DawerLayout 下面的主界面添加,DawerLayout 本身以及它下面的抽屉都不能添加,原因后面会说明,然后同样看一下内部实现:

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public void setColorBarForDrawer(@ColorInt int color, int alpha) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            ViewGroup decorView = (ViewGroup) window.getDecorView();
            int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
            if (navigationBarExist(activity)) {
                option = option | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
            }
            decorView.setSystemUiVisibility(option);
            window.setNavigationBarColor(Color.TRANSPARENT);
            window.setStatusBarColor(Color.TRANSPARENT);
            int alphaColor = alpha == 0 ? color : calculateColor(color, alpha);
            decorView.addView(createStatusBarView(activity, alphaColor), 0);
            if (navigationBarExist(activity)) {
                decorView.addView(createNavBarView(activity, alphaColor), 1);
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            ViewGroup decorView = (ViewGroup) window.getDecorView();
            int alphaColor = alpha == 0 ? color : calculateColor(color, alpha);
            decorView.addView(createStatusBarView(activity, alphaColor), 0);
            if (navigationBarExist(activity)) {
                window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
                decorView.addView(createNavBarView(activity, alphaColor), 1);
            }
        }
    }
    
    
    
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public void setColorBarForDrawer(@ColorInt int color) {
        setColorBarForDrawer(color, 0);
    }

    这里稍微有点复杂,参数的传递和前面是一样的,就不多解释了,对于 Android 5.0 以上的情况,首先添加前面两个 flag 保证布局内容能够覆盖到状态栏上面,然后判断是否存在导航栏,如果存在,再添加第三个 flag 保证布局内容可以覆盖到导航栏上面,然后状态栏和导航栏都设为透明色,此时相当于上面的完全透明的状态栏和导航栏,最后再分别在状态栏和导航栏上面添加一个 view 保证状态栏和导航栏有颜色,这样就既保证了 DrawerLayout 可以覆盖到状态栏和导航栏上面,又保证了 DrawerLayout 下面的主布局内容不会覆盖到状态栏和导航栏上面,最后的效果就是抽屉的内容是覆盖到状态栏和导航栏上面的,而住布局的内容不会覆盖到状态栏和导航栏的上面,然后对于 Android 4.4,其实和前面正常情况的设置自定义颜色的状态栏和导航栏是一样的,只是这里没有调用 setRootView 方法,而是在 DrawerLayout 下面的主布局中添加了 android:fitsSystemWindows="true",同样实现了抽屉的内容可以覆盖到状态栏和导航栏上面,而主布局的内容不会覆盖到状态栏和导航栏上面,最后的效果如下图


    抽屉未抽出

    抽屉抽出一半

    抽屉完全抽出

    大致内容也就这么多了,最后再把这个库的地址贴一遍:

    UltimateBar

    如果觉得这个库对你的开发有帮助,欢迎 star,欢迎 fork,如果发现有什么问题或者有什么修改建议,欢迎反馈,谢谢!



    作者:风魔龙郎
    链接:http://www.jianshu.com/p/b4d5a307f793
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    展开全文
  • Android 透明状态栏

    千次阅读 2019-03-04 14:50:04
    最近公司产品提出透明状态栏的要求,将一张背景填充满屏幕,自己记录一下: Android 透明状态栏:有两种,背景是图片还是纯色,下面分开讲: 1.当背景为图片时,布局可以这么写: 方法1,在代码onCreate()方法...

    转载:https://blog.csdn.net/fan7983377/article/details/51604657

    最近公司产品提出透明状态栏的要求,将一张背景填充满屏幕,自己记录一下:

    Android 透明状态栏:有两种,背景是图片还是纯色,下面分开讲:

    1.当背景为图片时,布局可以这么写:

    方法1,在代码onCreate()方法里书写下面代码:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Window window = getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.TRANSPARENT);
        window.setNavigationBarColor(Color.TRANSPARENT);
    }
    else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        Window window = getWindow();
        window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    }

    然后在xml跟布局,设置属性:android:fitsSystemWindows="true",代码如下:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        
        android:background="@drawable/bg_scenery"
        android:fitsSystemWindows="true">
    </LinearLayout>

    效果图:

    方法二:主要的操作都在style.xml 和 AndroidManifest.xml 中,Activity里面没有任何涉及到需要设置的代码,所以可以忽略不看。

    ps:

    首先需要到AndroidManifest中为指定的Activity设置Theme。但是需要注意的是,我们不能直接在values/style.xml直接去自定义 Translucet System Bar 的Theme,因为改特性仅兼容 Android 4.4 开始的平台,所以直接在values/style.xml声明引入,工程会报错。有些开发者朋友会在代码中去判断SDK的版本,然后再用代码设置Theme。虽然同样可以实现效果,但个人并不推崇这种做法。我所采取的方法则是建立多个SDK版本的values文件夹,系统会根据SDK的版本选择合适的Theme进行设置。大家可以看到上面我的工程里面有valuesvalues-v19values-v21

    该方法需要做下面三步设置:

    step1:在valuesvalues-v19values-v21的style.xml都设置一个 Translucent System Bar 风格的Theme

    values/style.xml

    <style name="ImageTranslucentTheme" parent="AppTheme">
        <!--在Android 4.4之前的版本上运行,直接跟随系统主题-->
    </style>

    values-v19/style.xml

    <style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
    </style>

    values-v21/style.xml

    <style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">false</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

    上面需要注意的地方是,无论你在哪个SDK版本的values目录下,设置了主题,都应该在最基本的values下设置一个同名的主题。这样才能确保你的app能够正常运行在 Android 4.4 以下的设备。否则,肯定会报找不到Theme的错误。

    step2:在AndroidManifest.xml中对指定Activity的theme进行设置

    <activity android:name=".activity.ImageActivity"
        android:theme="@style/ImageTranslucentTheme"/>

    step3:在Activity的布局文件中设置背景图片,同时,需要把android:fitsSystemWindows设置为true

    xml布局:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/bg_building"
        android:fitsSystemWindows="true">
    </LinearLayout>

    效果图:

    上面2中方法,如果仅仅需要ImageView控件覆盖状态栏,那么将android:fitsSystemWindows设置为false即可。

    xml布局:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/bg_building"
        android:fitsSystemWindows="false">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:scaleType="fitXY"
            android:src="@drawable/hehua"/>
    
    </LinearLayout>

    效果图:

    1.当背景为纯色时,

    由于它的Tab栏是纯色的,所以只要把系统通知栏的颜色设置和Tab栏的颜色一致即可,实现上相比方法一要简单很多。同样要到不同SDK版本的values下,创建一个同名的theme,在values-v21下,需要设置系统导航栏的颜色:

    values/style.xml

    <style name="ColorTranslucentTheme" parent="AppTheme">
    </style>

    values-v19/style.xml

    <style name="ColorTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
    </style>

    values-v21/style.xml

    <style name="ColorTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">false</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

    在AndroidManifest.xml中对指定Activity的theme进行设置

    <!--图片-->
    <activity android:name=".activity.ColorActivity"
        android:theme="@style/ColorTranslucentTheme"/>

    xml布局:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/bar_color"
        android:fitsSystemWindows="true">
    
        <!--标题布局-->
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:background="@color/bar_color">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="这是title栏"
                android:textColor="@android:color/white"
                android:textSize="20sp" />
        </RelativeLayout>
    
        <!--内容布局-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@android:color/white">
            <!--自己根据实际需求填写-->
    
        </LinearLayout>
    </LinearLayout>

    效果图:

    好了,以上就是沉浸式状态栏实现的全过程,但是还有一点值得注意的就是,如果我们activity比较多,每一个页面都添加android:fitsSystemWindows="true" 比较麻烦,我们需要改动一下:

    写一个基类BaseColorActivity.class,代码如下:

    public abstract class BaseColorActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//这一行注意!看本文最后的说明!!!!
    
            setContentView(getLayoutId());
    
            ViewGroup contentFrameLayout = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
            View parentView = contentFrameLayout.getChildAt(0);
            if(parentView != null && Build.VERSION.SDK_INT >= 14){
                parentView.setFitsSystemWindows(true);
            }
        }
    
        protected abstract int getLayoutId();
    }

    然后需要沉浸状态栏的activity继承该基类:

    public class ColorActivity extends BaseColorActivity {
    
        public static void startActivity(Context context){
            Intent intent = new Intent(context, ColorActivity.class);
            context.startActivity(intent);
        }
    
        @Override
        protected int getLayoutId() {
            return R.layout.activity_color;
        }
    }

    然后需要沉浸状态栏的activity的布局文件中就可以把android:fitsSystemWindows="true"这行代码给省略了!,其他设置还是按照一开始操作。

     

    写个工具类StatusBarCompat.class

    public class StatusBarCompat {
    
        private static final int INVALID_VAL = -1;
        private static final int COLOR_DEFAULT = Color.parseColor("#20000000");
    
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public static void compat(Activity activity, int statusColor)
        {
    
            //当前手机版本为5.0及以上 
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            {
                if (statusColor != INVALID_VAL)
                {
                    activity.getWindow().setStatusBarColor(statusColor);
                }
                return;
            }
    
            //当前手机版本为4.4
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
            {
                int color = COLOR_DEFAULT;
                ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
                if (statusColor != INVALID_VAL)
                {
                    color = statusColor;
                }
                View statusBarView = new View(activity);
                ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        getStatusBarHeight(activity));
                statusBarView.setBackgroundColor(color);
                contentView.addView(statusBarView, lp);
            }
    
        }
    
        public static void compat(Activity activity)
        {
            compat(activity, INVALID_VAL);
        }
    
    
        public static int getStatusBarHeight(Context context)
        {
            int result = 0;
            int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0)
            {
                result = context.getResources().getDimensionPixelSize(resourceId);
            }
            return result;
        }
    
    }

    使用方法:

    在当前activity的onCreate中,调用方法StatusBarCompat.compat就可以了:

    //第二个参数是想要设置的颜色

    StatusBarCompat.compat(this, Color.RED);

    如果嫌每个activity都要写有点麻烦,那就写个基类来完成这一步:

    public class BaseActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
            super.onCreate(savedInstanceState);
    
            StatusBarCompat.compat(this, Color.RED);
        }
    }

    关于上面代码中提示注意的那个地方的说明:

    隐藏系统title注意的两点:

    1. 继承AppCompatActivity时使用: 
      supportRequestWindowFeature(Window.FEATURENOTITLE)

    2. 继承activity时使用: 
      requestWindowFeature(Window.FEATURENOTITLE) 

     

     

     

     

    展开全文
  • 在我们的日常开发中,会经常遇到应用首页的顶部是个Banner(轮播图),好多Banner还延伸到我们的状态栏里面去了,既显得风格一致又显得简洁美观。第二种是顶部系统状态栏和App的导航栏一体化,不给用户突兀的感觉,...
  • 透明状态栏(沉浸式状态栏)

    千次阅读 2016-01-26 08:58:17
    透明状态栏(沉浸式状态栏)透明状态栏(Translucate StatusBar)是android从4.4开始模仿ios推出的一种模式,他可以改变状态栏的颜色,使其更加的与自己的app样式所统一android 4.4推出的状态栏为透明样式,但会有一...
  • win10全透明状态栏任务栏

    千次阅读 2019-03-30 16:02:22
    这个需要用到一个小工具 ... 上方下载 直接点启动 ...任务栏状态(选择一种 - 可以在除正常之外的每个状态上自定义): 模糊:会使任务略显模糊。 清除:透明任务。 正常:常规Windows...
  • Android沉浸式状态栏(透明状态栏)最佳实现

    万次阅读 多人点赞 2017-12-15 09:29:21
    Android沉浸式状态栏(透明状态栏)最佳实现 在Android4.4之前,我们的应用没法改变手机的状态栏颜色,当我们打开应用时,会出现上图中左侧的画面,在屏幕的顶部有一条黑色的状态栏,和应用的风格非常不协调;为了...
  • Android透明状态栏与沉浸模式全解

    千次阅读 2017-04-03 13:04:39
    Android透明状态栏与沉浸模式全解现在如今利用状态栏做文章的主要就是如下四种场景了,先上图 - 网易云音乐 状态栏与标题栏同色,无缝衔接 - 多看阅读 全屏沉浸阅读(视频,游戏同理) - 淘宝 状态栏深色 - ...
  • android设置透明状态栏

    万次阅读 2020-05-21 18:23:17
    沉浸式状态栏:就是你看视频(横屏)的时候没有状态栏,就算你点击屏幕一下也不会出现状态栏的(需要从上...透明式状态栏:就式状态栏背景与应用背景相同,这就是*透明状态栏*,如下图博主的手机主界面就是透明状态栏
  • 实现透明状态栏的方法网上有很多,但是基本都是对Activity的,没有Dialog、DialogFragment和PopupWindow的,这样就会出现一个对话框后,状态栏变的不协调。 1.Dialog和DialogFragment在设置style的时候api19及以上...
  • 开发中为了美观需要将状态栏设置为半透明/全透明, 多个界面需求不同,所以需要在代码中来根据不同情况设置设置之前你需要知道:默认情况下状态栏是有高度的,app内容是在其之下。但是设置半透明/透明之后,状态栏又...
  • 沉浸式状态栏指的是,状态栏隐藏,在手指做了相关操作后,状态栏显示出来,例如视频播放器,在播放视频时是隐藏状态栏的,但是点击屏幕的时候,状态栏会显示出来,再例如文本阅读器,在阅读的时候是全屏的,然后从...
  • Cordova 实现沉浸式(透明状态栏效果

    万次阅读 热门讨论 2017-07-05 15:04:31
    沉浸式状态栏(Immersive Mode)和透明状态栏(Translucent Bar)。这两个概念很多地方的解释都不是很清晰,所以导致很多人都各有各的认识。所以这里我也有一个自己的认识,笔者认为沉浸式状态栏也可以说是全屏模式...
  • android api19开始我们就能对顶部状态栏和底部导航栏进行半透明处理了,而api21开始则可以实现全透明状态栏与导航栏以及开启沉浸模式,至于什么是沉浸模式,大家百度一下应该就都知道了,有一点需要强调的是全透明...
  • Window window = getWindow(); window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN ...
  • android 全屏以及透明状态栏总结

    千次阅读 2016-10-28 14:58:55
    一般启动页面的要求都是全屏显示,全屏显示可能会出现一个隐藏状态栏的动画,用户体验不是很好,现在基本都是做成透明状态栏和ios 显示的效果一样,所以在此总结一下。下面是效果图,不是很明显是应为我全局设置的...
  • Android标题透明沉浸式UI

    万次阅读 2016-06-01 11:21:33
    透明状态栏加透明导航栏style的配置android从4.4开始,开始支持UI使用StatusBar与NavigationBar的范围。所以要进行下面的配置:在value中的styles.xml中设置<!-- Base application theme. --> ...
  • 变色状态栏(透明状态栏):指的是状态栏与导航栏颜色相同,或者透明 沉浸式状态栏:,状态栏隐藏,在手指做了相关操作后,状态栏显示出来,例如视频播放器,在播放视频时是隐藏状态栏的,但是点击屏幕的时候,状态...
  • UltimateBar ...1.四种效果,自定义颜色的状态栏和导航栏,半透明状态栏和导航栏, 沉浸式状态栏和导航栏,隐藏状态栏和导航栏; 2.可以自定义状态栏和导航栏的颜色和透明度; 3.KITKAT(And
1 2 3 4 5 ... 20
收藏数 51,079
精华内容 20,431
关键字:

透明状态栏