android 沉浸式状态栏

1,907 阅读3分钟
原文链接: jandzy.com

img

状态栏透明

一般状态栏(colorPrimaryDark)是黑色的,变透明有两种方式

在style文件中修改



   
  @color/colorPrimary
  @color/colorPrimaryDark
  @color/colorAccent
  true
  true
  

主要是android:windowTranslucentStatus设置为true是拉升到顶部状态栏,并且定义顶部状态栏透明。(其中colorPrimaryDark就是默认状态栏的颜色)

在代码中修改

在setContentView之前调用

if(VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
                                //透明状态栏
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                                //透明导航栏
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
                        }

设置完之后效果如下图,
状态栏透明拉伸
会发现状态栏和toolbar重叠到了一起,网上说的有很多种方法,比如加padding值等,发现一个比较方便的方法,在toolbar中添加fitSystemwindows属性即可


    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true"
    android:background="#ff0000">

关于fitSystwindows属性:

官方描述:
Boolean internal attribute to adjust view layout based on system windows such as the status bar. If true, adjusts the padding of this view to leave space for the system windows. Will only take effect if this view is in a non-embedded activity.

简单描述:

这个一个boolean值的内部属性,让view可以根据系统窗口(如status bar)来调整自己的布局,如果值为true,就会调整view的paingding属性来给system windows留出空间….

实际效果:

当status bar为透明或半透明时(4.4以上),系统会设置view的paddingTop值为一个适合的值(status bar的高度)让view的内容不被上拉到状态栏,当在不占据status bar的情况下(4.4以下)会设置paddingTop值为0(因为没有占据status bar所以不用留出空间)。

添加fitSystemWindows属性后效果如图:
fitSystemWindows效果
现在状态栏的颜色就和toolbar颜色一致啦。

另外,除了使用fitSystemWindows属性外还可以给toolbar添加pddingTop=25来达到同样的效果。使用fitSystemWindows的时候可能会有坑,比如我的仿今日头条的一个小项目———“今日小头条”,底部用的TabWidgt,此时整个布局相当于在FrameLayout之中,如果在用fitSystemWindows的话会发现只有一个可以,这时候就需要用paddingTop来实现。这也算是一个小坑。

通过Palette动态改变颜色

Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
           @Override
           public void onGenerated(Palette palette) {
               Palette.Swatch swatch = palette.getVibrantSwatch();
               if(swatch!=null){
                   toolbar.setBackgroundColor(swatch.getRgb());
               }else{
                   if(palette.getMutedSwatch()!=null) toolbar.setBackgroundColor(palette.getMutedSwatch().getRgb());
               }
           }
       });

Palette是android 5.0后添加的新特性,主要用途是通过一个从bitmap中获得你想要的色调,然后用来适配app达到色调一致的效果。

使用Palette

  1. 先添加gradle依赖

    dependencies {

    compile 'com.android.support:+'
    compile 'com.android.support:+'
    

    }

  1. 使用Palette
/**
 * A helper class to extract prominent colors from an image.
 * 

* A number of colors with different profiles are extracted from the image: *

    *
  • Vibrant
  • //充满活力的色调 *
  • Vibrant Dark
  • //充满活力的黑 *
  • Vibrant Light
  • //充满活力的亮 *
  • Muted
  • //柔和的色调 *
  • Muted Dark
  • //柔和的黑 *
  • Muted Light
  • //柔和的亮 *
* These can be retrieved from the appropriate getter method. * *

* Instances are created with a {@link Builder} which supports several options to tweak the * generated Palette. See that class' documentation for more information. *

* Generation should always be completed on a background thread, ideally the one in * which you load your image on. {@link Builder} supports both synchronous and asynchronous * generation: * * * // Synchronous * Palette p = Palette.from(bitmap).generate(); * * // Asynchronous * Palette.from(bitmap).generate(new PaletteAsyncListener() { * public void onGenerated(Palette p) { * // Use generated instance * } * }); * */

直接看Palette类的注释,获取Palette有两种方法,同步和异步。其中Palette对象包含六种色调,获得palette对象后,通过palette.getVibrantSwatch()等不同的色调获取Palette.Swatch内部类,通过swatch对象可以获取到具体的rgb、hsl等信息。然后对相应的组件设置颜色即可。