沉浸式狀態(tài)欄和透明狀態(tài)欄

前言

一般手機的界面上都會有:狀態(tài)欄、標題欄、導(dǎo)航欄等固定的布局;


樣式圖

區(qū)別

  • 沉浸式狀態(tài)欄:這種樣式其實就是把狀態(tài)欄、標題欄、導(dǎo)航欄都去掉,讓整個屏幕都只顯示應(yīng)用要顯示的界面,從而給用戶一種“沉浸”在里面的感覺!


    效果圖1

    效果圖2
  • 透明狀態(tài)欄:這種樣式其實就是把狀態(tài)欄和標題欄配置成一種顏色,達到一種美觀效果!


    效果圖
透明狀態(tài)欄

4.4版本一下沒辦法配置透明欄,4.4、5.0、6.0不同版本又會有不同的效果,所以我們要做好適配工作

實現(xiàn)步驟
  • 去掉系統(tǒng)自帶的標題欄,采用自定義的狀態(tài)欄(自定義狀態(tài)欄推薦使用Toolbar)

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

  • 設(shè)置狀態(tài)欄為透明
    • 第一種方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  }
  super.onCreate(savedInstanceState);
}
  • 第二種方法:

使用android:windowTranslucentStatus屬性需要在res目錄下新建values-v19文件夾,style文件要放在里面。

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
      <item name="android:windowTranslucentStatus">true</item>
</style>
  • 防止狀態(tài)欄和自定義標題欄重合
    • 第一種方法:
      在Activity的根布局文件中添加

android:fitsSystemWindows="true"
```

  • 第二種方法:

給在Toolbar的上方添加一個和狀態(tài)欄高度一樣的Veiw,并將這個View的背景色設(shè)置成和Toolbar的背景色一樣。也可以直接給Toobar設(shè)置paddingTop等于狀態(tài)欄高。

public static void setToolBarPaddingHeight(Window window, View view) {
      //TODO: 代碼設(shè)置標題欄paddingtop為狀態(tài)欄的高
      int statusBarHeight = getStatusBarHeight(window.getContext());
      view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());
  }
public static int getStatusBarHeight(Context context) {
      //TODO: 算取狀態(tài)欄的高
      int result = 0;
      int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
      if (resourceId > 0) {
          result = context.getResources().getDimensionPixelSize(resourceId);
      }
      return result;
  }

通過以上就可以實現(xiàn)透明狀態(tài)欄了。總的來說還是比較簡單的,下面貼一下只用代碼就可以實現(xiàn)透明狀態(tài)欄的工具類!

/**
* Created by ML on 2017/3/9.
* 前言:
* 在Android4.4之前,我們的應(yīng)用沒法改變手機的狀態(tài)欄顏色,google在Android4.4以后提供了設(shè)置狀態(tài)欄的方法;
* 沉浸式狀態(tài)欄和透明式狀態(tài)欄是不同的概念;
*/

public class UIUtils {
   //TODO: 透明狀態(tài)欄相關(guān)方法
   /**
    * 相關(guān)Flag
    WindowManager.LayoutParams.FLAG_FULLSCREEN
    隱藏狀態(tài)欄

    View.SYSTEM_UI_FLAG_VISIBLE API 14
    默認標記

    View.SYSTEM_UI_FLAG_LOW_PROFILE API 14
    低調(diào)模式, 會隱藏不重要的狀態(tài)欄圖標

    View.SYSTEM_UI_FLAG_LAYOUT_STABLE API 16
    保持整個View穩(wěn)定, 常和控制System UI懸浮, 隱藏的Flags共用, 使View不會因為System UI的變化而重新layout

    View.SYSTEM_UI_FLAG_FULLSCREEN API 16
    狀態(tài)欄隱藏,效果同設(shè)置WindowManager.LayoutParams.FLAG_FULLSCREEN

    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN API 16
    視圖延伸至狀態(tài)欄區(qū)域,狀態(tài)欄上浮于視圖之上

    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION API 14
    隱藏導(dǎo)航欄

    View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION API 16
    視圖延伸至導(dǎo)航欄區(qū)域,導(dǎo)航欄上浮于視圖之上

    View.SYSTEM_UI_FLAG_IMMERSIVE API 19
    沉浸模式, 隱藏狀態(tài)欄和導(dǎo)航欄, 并且在第一次會彈泡提醒, 并且在狀態(tài)欄區(qū)域滑動可以呼出狀態(tài)欄(這樣會系統(tǒng)會清楚之前設(shè)置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION標志)。使之生效,需要和View.SYSTEM_UI_FLAG_FULLSCREEN,View.SYSTEM_UI_FLAG_HIDE_NAVIGATION中的一個或兩個同時設(shè)置。

    View.SYSTEM_UI_FLAG_IMMERSIVE_STIKY API 19
    與上面唯一的區(qū)別是, 呼出隱藏的狀態(tài)欄后不會清除之前設(shè)置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION標志,在一段時間后將再次隱藏系統(tǒng)欄)
    */

   /**
    * 實現(xiàn)透明狀態(tài)欄且不需要配置android:fitsSystemWindows="true"
    * 注意::標題欄根布局高度必須是自適應(yīng)
    *
    * @param window
    * @param view   標題欄根布局(根布局高度必須是自適應(yīng))
    */
   public static void setScreenTranslucentStatus(Window window, int Color, View view) {
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
           setTranslucentStatusForSDK_LOLLIPOP(window, Color);
       } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
           setTranslucentStatusForSDK_KITKAT(window);
       }
       setToolBarPaddingHeight(window, view);
   }

   /**
    * 實現(xiàn)透明狀態(tài)欄需要配置android:fitsSystemWindows="true"
    * 注意::標題欄根布局高度必須是自適應(yīng)
    *
    * @param window
    */
   public static void setTranslucentStatusXML(Window window, int color) {
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
           setTranslucentStatusForSDK_LOLLIPOP(window, color);
       } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
           setTranslucentStatusForSDK_KITKAT(window);
       }
   }

   /**
    * 設(shè)置Android狀態(tài)欄的字體顏色,狀態(tài)欄為亮色的時候字體和圖標是黑色,狀態(tài)欄為暗色的時候字體和圖標為白色
    *
    * @param dark 狀態(tài)欄字體和圖標是否為深色
    */
   public static void setStatusBarFontDark(@NonNull Window window, @NonNull boolean dark, int color, View view) {
       //TODO: 實現(xiàn)狀態(tài)欄白底黑字
       if (PhoneUtil.isMIUI()) {
           setMIUIBarFontDark(window, dark, view);
       } else if (PhoneUtil.isFlyme()) {
           setFlymeBarFontDark(window, dark, view);
       } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
           setSDK_MBarFontDark(window, dark, view);
       } else {
           L.i("Android原生6.0一下系統(tǒng)>>>>>>>>>>>>>>>實現(xiàn)狀態(tài)欄灰底白字");
           setToolBarBgColor(window, color, view);
       }
   }

   public static void setSDK_MBarFontDark(@NonNull Window window, @NonNull boolean dark, View view) {
       //TODO: 配置Android原生6.0系統(tǒng)狀態(tài)欄白底黑字
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
           if (dark) {
               setScreenTranslucentStatus(window, Color.TRANSPARENT, view);
               window.getDecorView().setSystemUiVisibility(
                       View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                               | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
               L.i("Android原生6.0系統(tǒng)>>>>>>>>>>>>>>>狀態(tài)欄白底黑字");
           }
       }
   }

   public static void setFlymeBarFontDark(@NonNull Window window, @NonNull boolean dark, View view) {
       //TODO: 配置魅族系統(tǒng)狀態(tài)欄白底黑字
       try {
           setScreenTranslucentStatus(window, Color.TRANSPARENT, view);
           WindowManager.LayoutParams lp = window.getAttributes();
           Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
           Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
           darkFlag.setAccessible(true);
           meizuFlags.setAccessible(true);
           int bit = darkFlag.getInt(null);
           int value = meizuFlags.getInt(lp);
           if (dark) {
               value |= bit;
           } else {
               value &= ~bit;
           }
           meizuFlags.setInt(lp, value);
           window.setAttributes(lp);
           L.i("小米系統(tǒng)>>>>>>>>>>>>>>>狀態(tài)欄白底黑字");
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

   public static void setMIUIBarFontDark(@NonNull Window window, @NonNull boolean dark, View view) {
       //TODO: 配置小米系統(tǒng)狀態(tài)欄白底黑字
       try {
           setScreenTranslucentStatus(window, Color.TRANSPARENT, view);
           Class clazz = window.getClass();
           Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
           Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
           int darkModeFlag = field.getInt(layoutParams);
           Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
           if (dark) {    //狀態(tài)欄亮色且黑色字體
               extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
           } else {       //清除黑色字體
               extraFlagField.invoke(window, 0, darkModeFlag);
           }
           L.i("小米系統(tǒng)>>>>>>>>>>>>>>>狀態(tài)欄白底黑字");
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

   public static void setToolBarBgColor(Window window, int color, View view) {
       //TODO: Android原生5.0一下系統(tǒng)實現(xiàn)灰底白字
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
           setTranslucentStatusForSDK_LOLLIPOP(window, color);
           setToolBarPaddingHeight(window, view);
       } else {
           //            setTranslucentStatusForSDK_KITKAT(window);
           L.i("Android原生4.4以上5.0一下系統(tǒng)需要自己手動在狀態(tài)欄加view實現(xiàn)灰底白字(http://www.lxweimin.com/p/a44c119d6ef7)");
       }
   }

   public static void setToolBarPaddingHeight(Window window, View view) {
       //TODO: 代碼設(shè)置標題欄paddingtop為狀態(tài)欄的高
       int statusBarHeight = getStatusBarHeight(window.getContext());
       view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());
   }

   public static void setTranslucentStatusForSDK_KITKAT(Window window) {
       //TODO: 4.4以上系統(tǒng)狀態(tài)欄透明
       window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
   }

   public static void setTranslucentStatusForSDK_LOLLIPOP(Window window, int Color) {
       //TODO:  5.0以上系統(tǒng)狀態(tài)欄透明
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
           window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
           window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
           window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
           window.setStatusBarColor(Color);  //TODO: 指定狀態(tài)欄的顏色和布局的顏色相同
       }
   }

   public static int getStatusBarHeight(Context context) {
       //TODO: 算取狀態(tài)欄的高
       int result = 0;
       int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
       if (resourceId > 0) {
           result = context.getResources().getDimensionPixelSize(resourceId);
       }
       return result;
    }
   ```
#### 沉浸式狀態(tài)欄


重寫Activity的onWindowFocusChanged()方法,然后加入如下邏輯即可:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= 19) {
View decorView = 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);
}
}


[參考文章1](http://blog.csdn.net/xuchao_blog/article/details/54693482)
[參考文章2](http://www.lxweimin.com/p/a44c119d6ef7)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容