Android 狀態(tài)欄和虛擬按鍵背景顏色的變化

  • 實現(xiàn)狀態(tài)欄背景的設(shè)置
    狀態(tài)欄工具類

    public class StatusBarUtil {
    /**
    * 設(shè)置沉浸式狀態(tài)欄
    *
    * @param activity 需要設(shè)置的activity
    */
    public static void setTransparent(Activity activity) {
      //API19一下不考慮
      if (Build.VERSION.SDK_INT < 
      Build.VERSION_CODES.KITKAT) {
          return;
      }
      transparentStatusBar(activity);
      setStatusBarTextColor(activity, Color.WHITE);
      }
    
     /**
     * 使狀態(tài)欄透明
     */
      @TargetApi(Build.VERSION_CODES.KITKAT)
      private static void transparentStatusBar(Activity activity) {
      Window window = activity.getWindow();
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
          window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);     
          window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
          //設(shè)置虛擬按鍵背景透明,同時該屬性會實現(xiàn)沉浸式狀態(tài)欄
          window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    
     window.setStatusBarColor(Color.TRANSPARENT);
    // window.setNavigationBarColor(Color.BLACK);
      } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
          window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
          window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
      }
     }
    
     /**
    * Android 6.0 以上設(shè)置狀態(tài)欄顏色
    */
    protected static void setStatusBarTextColor(Activity activity, @ColorInt int color) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
          // 如果亮色,設(shè)置狀態(tài)欄文字為黑色
          if (isLightColor(color)) {
              activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
          } else {
              activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
          }
      }
     }
    
     /**
     * 判斷顏色是不是亮色
     *
     * @param color
     * @return
     * @from https://stackoverflow.com/questions/24260853/check-if-color-is-dark-or-light-in-android
     */
    private static boolean isLightColor(@ColorInt int color) {
      return ColorUtils.calculateLuminance(color) >= 0.5;
     }
    /**
     * 將布局設(shè)置為狀態(tài)欄的高度
     * 
     * @param context
     * @param view
     */
     public static void setStatusBarHeight(Context context, View view) {
      // 獲得狀態(tài)欄高度
      int height = getStatusBarHeight(context);
      ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
      layoutParams.height = height;
      view.setLayoutParams(layoutParams);
     //        status_bar.requestLayout();//請求重新布局
    }
    
    /**
    * 獲取狀態(tài)欄高度
    *
    * @param context context
    * @return 狀態(tài)欄高度
    */
    public static int getStatusBarHeight(Context context) {
      // 獲得狀態(tài)欄高度
      int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
      return context.getResources().getDimensionPixelSize(resourceId);
    }
    }
    

該方法中,首先判斷API版本,由于API19以下沒有設(shè)置狀態(tài)欄的方法,所以我們只考慮19以上的版本,接著調(diào)用了transparentStatusBar()方法,根據(jù)API21為分界,分別實現(xiàn)狀態(tài)欄背景的透明,然后是調(diào)用setStatusBarTextColor()方法,設(shè)置狀態(tài)欄字體的顏色。

  • 實現(xiàn)效果:
    1、沉浸式


    image
  • 2、自定義狀態(tài)欄,我設(shè)置的背景為白色
image

如果要填充自己需要的導(dǎo)航欄顏色的話,可以自己創(chuàng)建一個導(dǎo)航欄布局layout_head,

<?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"
android:background="@color/bgGray"
android:orientation="vertical">

<View
    android:id="@+id/status_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"/>
 </LinearLayout>

通過以下代碼:

    protected View getHeadView() {
    View view = View.inflate(activity, R.layout.layout_head, null);
    View status_bar = view.findViewById(R.id.status_bar);
    //status_bar .setBackground()

    StatusBarUtil.setStatusBarHeight(activity, status_bar);

    return view;
}
// frameLayout是你的activity留出的狀態(tài)欄布局
frameLayout.addView(getHeadView());

這樣,就可以設(shè)置自己想要的狀態(tài)欄的顏色和高度了。

  • 虛擬按鍵背景顏色的設(shè)置

虛擬按鍵工具類

public class NavigationBarUtil {
public static void initActivity(View content) {
    new NavigationBarUtil(content);
}

/**
 * 被監(jiān)聽的視圖
 */
private View mObserved;
/**
 * 視圖變化前的可用高度
 */
private int usableHeightView;
private ViewGroup.LayoutParams layoutParams;

private NavigationBarUtil(View content) {
    mObserved = content;
    //給View添加全局的布局監(jiān)聽器監(jiān)聽視圖的變化
    mObserved.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            resetViewHeight1();

        }
    });
    layoutParams = mObserved.getLayoutParams();
}


private int usableHeight = 0;
private void resetViewHeight1() {
    int usableHeightViewNow = CalculateAvailableHeight();
    //比較布局變化前后的View的可用高度
    InputMethodManager inputMethodManager = (InputMethodManager) VankeApplication.getApplication().getSystemService(Context.INPUT_METHOD_SERVICE);
    Rect rect = new Rect();
    mObserved.getWindowVisibleDisplayFrame(rect);


    usableHeight = Math.max(usableHeight, rect.bottom);
    if (inputMethodManager.isActive() && usableHeight > rect.bottom) {//軟鍵盤顯示,導(dǎo)致界面布局改變
        return;
    }

    if (usableHeightViewNow != usableHeightView) {
        //如果兩次高度不一致
        //將當(dāng)前的View的可用高度設(shè)置成View的實際高度
        Configuration mConfiguration = VankeApplication.getApplication().getResources().getConfiguration(); //獲取設(shè)置的配置信息
        int ori = mConfiguration.orientation; //獲取屏幕方向
        if (ori == Configuration.ORIENTATION_LANDSCAPE) {
            //橫屏
            layoutParams.width = usableHeightViewNow;
        } else if (ori == Configuration.ORIENTATION_PORTRAIT) {
            //豎屏
            layoutParams.height = usableHeightViewNow;
        }

        mObserved.requestLayout();//請求重新布局
        usableHeightView = usableHeightViewNow;
    }
}

/**
 * 計算試圖高度
 *
 * @return
 */
private int CalculateAvailableHeight() {
    Rect r = new Rect();
    mObserved.getWindowVisibleDisplayFrame(r);
    Configuration mConfiguration = VankeApplication.getApplication().getResources().getConfiguration(); //獲取設(shè)置的配置信息
    int ori = mConfiguration.orientation; //獲取屏幕方向
    if (ori == Configuration.ORIENTATION_LANDSCAPE) {
        //橫屏
        return (r.right);
    } else if (ori == Configuration.ORIENTATION_PORTRAIT) {
        //豎屏
        return (r.bottom);
    }
   //        return (r.bottom - r.top);//如果不是沉浸狀態(tài)欄,需要減去頂部高度
    return (r.bottom);//如果是沉浸狀態(tài)欄
}

/**
 * 判斷底部是否有虛擬鍵
 *
 * @param context
 * @return
 */
public static boolean hasNavigationBar(Context context) {
    boolean hasNavigationBar = false;
    Resources rs = context.getResources();
    int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
    if (id > 0) {
        hasNavigationBar = rs.getBoolean(id);
    }
    try {
        Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
        Method m = systemPropertiesClass.getMethod("get", String.class);
        String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
        if ("1".equals(navBarOverride)) {
            hasNavigationBar = false;
        } else if ("0".equals(navBarOverride)) {
            hasNavigationBar = true;
        }
    } catch (Exception e) {

    }
    return hasNavigationBar;

}

}

調(diào)用方式(在onCreate()中調(diào)用):

  if (NavigationBarUtil.hasNavigationBar(this)) {
        NavigationBarUtil.initActivity(findViewById(android.R.id.content));
    }

這里我直接使用的系統(tǒng)的布局,首先調(diào)用hasNavigationBar()判斷是否有虛擬按鍵,如果有,則調(diào)用initActivity()初始化NavigationBarUtil工具類,在工具類的構(gòu)造方法中,給傳入的view添加了全局的布局監(jiān)聽器,監(jiān)聽視圖的變化,在監(jiān)聽器中,調(diào)用resetViewHeight1()方法,里面通過CalculateAvailableHeight()獲取虛擬按鍵的高度,根據(jù)橫豎屏的不同,分別設(shè)置了view的高度,實現(xiàn)了虛擬按鍵布局背景的填充。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容