Browse Source

1.状态栏完美结局

zhangxinyu 5 years ago
parent
commit
b0c9d76c7c

+ 11 - 1
app/src/main/java/com/webrain/happywork/ui/base/BaseActivity.java

@@ -23,9 +23,10 @@ public abstract class BaseActivity<P extends IPresenter> extends RxAppCompatActi
         mContext = this;
         mvpPresenter = bindPresenter();
         mBaseHolder = new BaseActivityHolder(this, isImmersion());
-        mBaseHolder.initActionBar(isShowStatusTitle(), isShowActionBar());
         mBaseHolder.initActivityContent(getLayoutId());
         setContentView(mBaseHolder.getView());
+        //actionbar 后执行
+        mBaseHolder.initActionBar(isShowPrimordialStatus(), isShowStatusTitle(), isShowActionBar());
 
     }
 
@@ -76,6 +77,15 @@ public abstract class BaseActivity<P extends IPresenter> extends RxAppCompatActi
     }
 
     /**
+     * 是否显示原生状态栏
+     *
+     * @return
+     */
+    public boolean isShowPrimordialStatus() {
+        return false;
+    }
+
+    /**
      * 是否显示沉浸式
      *
      * @return

+ 6 - 10
app/src/main/java/com/webrain/happywork/ui/base/BaseActivityHolder.java

@@ -13,6 +13,7 @@ import android.widget.TextView;
 import com.webrain.baselibrary.utils.PxUtils;
 import com.webrain.happywork.R;
 import com.webrain.happywork.callback.OnActionBarMenuClickListener;
+import com.webrain.happywork.utils.ActionBarUtils;
 
 import butterknife.BindView;
 import butterknife.ButterKnife;
@@ -76,12 +77,6 @@ public class BaseActivityHolder extends BaseViewHolder {
     void onClick(View view) {
         switch (view.getId()) {
             case R.id.ll_back:
-                if (onBackClickListener != null) {
-                    onBackClickListener.onClick(view);
-                } else {
-                    mContext.finish();
-                }
-                break;
             case R.id.ll_immersion_back:
                 if (onBackClickListener != null) {
                     onBackClickListener.onClick(view);
@@ -95,14 +90,15 @@ public class BaseActivityHolder extends BaseViewHolder {
                 break;
         }
     }
-
     /**
      * 设置标题和状态栏
      *
-     * @param isShowStatus
-     * @param isShowActionBar
+     * @param isShowPrimordialStatus 是否显示原生状态栏
+     * @param isShowStatus           是否显示状态栏
+     * @param isShowActionBar        是否显示actionbar
      */
-    public void initActionBar(boolean isShowStatus, boolean isShowActionBar) {
+    public void initActionBar(boolean isShowPrimordialStatus, boolean isShowStatus, boolean isShowActionBar) {
+        ActionBarUtils.initStatus(mContext, isShowPrimordialStatus, false, true);
         if (isImmersion) {
             //设置沉浸式头部高度
             RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) llImmersionTitle.getLayoutParams();

+ 240 - 0
app/src/main/java/com/webrain/happywork/utils/ActionBarUtils.java

@@ -0,0 +1,240 @@
+package com.webrain.happywork.utils;
+
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Color;
+import android.os.Build;
+import android.support.annotation.IntDef;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+
+
+import com.webrain.baselibrary.manager.SystemBarTintManager;
+import com.webrain.baselibrary.utils.OSUtils;
+import com.webrain.happywork.R;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+public class ActionBarUtils {
+    public final static int TYPE_MIUI = 0;
+    public final static int TYPE_FLYME = 1;
+    public final static int TYPE_M = 3;//6.0
+
+    @IntDef({TYPE_MIUI,
+            TYPE_FLYME,
+            TYPE_M})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface ViewType {
+    }
+
+    /**
+     * 初始化状态栏
+     *
+     * @param isShowStatus       是否显示状态栏
+     * @param isFitSystemWindows 是否布局预留状态栏空间
+     * @param isDark             是否为深色模式
+     */
+    public static void initStatus(AppCompatActivity mContext, boolean isShowStatus, boolean isFitSystemWindows, boolean isDark) {
+        ActionBarUtils.setRootViewFitsSystemWindows(mContext, isFitSystemWindows);
+        ActionBarUtils.setStatusBarColor(mContext, mContext.getResources().getColor(R.color.white));
+        //设置状态栏透明
+        if (!isShowStatus)
+            ActionBarUtils.setTranslucentStatus(mContext);
+        //一般的手机的状态栏文字和图标都是白色的, 可如果你的应用也是纯白色的, 或导致状态栏文字看不清
+        //所以如果你是这种情况,请使用以下代码, 设置状态使用深色文字图标风格, 否则你可以选择性注释掉这个if内容
+        if (!ActionBarUtils.setStatusBarDarkTheme(mContext, isDark)) {
+            //如果不支持设置深色风格 为了兼容总不能让状态栏白白的看不清, 于是设置一个状态栏颜色为半透明,
+            //这样半透明+白=灰, 状态栏的文字能看得清
+            ActionBarUtils.setStatusBarColor(mContext, 0x55000000);
+        }
+    }
+
+    /**
+     * 修改状态栏颜色,支持4.4以上版本
+     *
+     * @param colorId 颜色
+     */
+    public static void setStatusBarColor(Activity activity, int colorId) {
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            Window window = activity.getWindow();
+            window.setStatusBarColor(colorId);
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            //使用SystemBarTintManager,需要先将状态栏设置为透明
+            setTranslucentStatus(activity);
+            SystemBarTintManager systemBarTintManager = new SystemBarTintManager(activity);
+            systemBarTintManager.setStatusBarTintEnabled(true);//显示状态栏
+            systemBarTintManager.setStatusBarTintColor(colorId);//设置状态栏颜色
+        }
+    }
+
+    /**
+     * 设置状态栏透明
+     */
+    @TargetApi(19)
+    public static void setTranslucentStatus(Activity activity) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            //5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色
+            Window window = activity.getWindow();
+            View decorView = window.getDecorView();
+            //两个 flag 要结合使用,表示让应用的主体内容占用系统状态栏的空间
+            int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+            decorView.setSystemUiVisibility(option);
+            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 = activity.getWindow();
+            WindowManager.LayoutParams attributes = window.getAttributes();
+            int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
+            attributes.flags |= flagTranslucentStatus;
+            //int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
+            //attributes.flags |= flagTranslucentNavigation;
+            window.setAttributes(attributes);
+        }
+    }
+
+
+    /**
+     * 代码实现android:fitsSystemWindows
+     *
+     * @param activity
+     */
+    public static void setRootViewFitsSystemWindows(Activity activity, boolean fitSystemWindows) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            ViewGroup winContent = (ViewGroup) activity.findViewById(android.R.id.content);
+            if (winContent.getChildCount() > 0) {
+                ViewGroup rootView = (ViewGroup) winContent.getChildAt(0);
+                if (rootView != null) {
+                    rootView.setFitsSystemWindows(fitSystemWindows);
+                }
+            }
+        }
+
+    }
+
+
+    /**
+     * 设置状态栏深色浅色切换
+     */
+    public static boolean setStatusBarDarkTheme(Activity activity, boolean dark) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+                setStatusBarFontIconDark(activity, TYPE_M, dark);
+            } else if (OSUtils.isMiui()) {
+                setStatusBarFontIconDark(activity, TYPE_MIUI, dark);
+            } else if (OSUtils.isFlyme()) {
+                setStatusBarFontIconDark(activity, TYPE_FLYME, dark);
+            } else {//其他情况
+                return false;
+            }
+
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 设置 状态栏深色浅色切换
+     */
+    public static boolean setStatusBarFontIconDark(Activity activity, @ViewType int type, boolean dark) {
+        switch (type) {
+            case TYPE_MIUI:
+                return setMiuiUI(activity, dark);
+            case TYPE_FLYME:
+                return setFlymeUI(activity, dark);
+            case TYPE_M:
+            default:
+                return setCommonUI(activity, dark);
+        }
+    }
+
+    //设置6.0 状态栏深色浅色切换
+    public static boolean setCommonUI(Activity activity, boolean dark) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            View decorView = activity.getWindow().getDecorView();
+            if (decorView != null) {
+                int vis = decorView.getSystemUiVisibility();
+                if (dark) {
+                    vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+                } else {
+                    vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+                }
+                if (decorView.getSystemUiVisibility() != vis) {
+                    decorView.setSystemUiVisibility(vis);
+                }
+                return true;
+            }
+        }
+        return false;
+
+    }
+
+    //设置Flyme 状态栏深色浅色切换
+    public static boolean setFlymeUI(Activity activity, boolean dark) {
+        try {
+            Window window = activity.getWindow();
+            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);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    //设置MIUI 状态栏深色浅色切换
+    public static boolean setMiuiUI(Activity activity, boolean dark) {
+        try {
+            Window window = activity.getWindow();
+            Class<?> clazz = activity.getWindow().getClass();
+            @SuppressLint("PrivateApi") 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.getDeclaredMethod("setExtraFlags", int.class, int.class);
+            extraFlagField.setAccessible(true);
+            if (dark) {    //状态栏亮色且黑色字体
+                extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
+            } else {
+                extraFlagField.invoke(window, 0, darkModeFlag);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    //获取状态栏高度
+    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;
+    }
+}

+ 0 - 1
app/src/main/res/values/styles.xml

@@ -7,7 +7,6 @@
         <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
         <item name="colorAccent">@color/colorAccent</item>
         <item name="android:windowBackground">@mipmap/ic_start_bg</item>
-        <item name="android:windowTranslucentStatus">true</item><!--沉静式-->
     </style>
 
     <style name="area_pop_anim_style">

+ 4 - 1
baselibrary/src/main/AndroidManifest.xml

@@ -1,2 +1,5 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.webrain.baselibrary" />
+    package="com.webrain.baselibrary" >
+
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+</manifest>

+ 550 - 0
baselibrary/src/main/java/com/webrain/baselibrary/manager/SystemBarTintManager.java

@@ -0,0 +1,550 @@
+package com.webrain.baselibrary.manager;
+
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.FrameLayout.LayoutParams;
+
+import java.lang.reflect.Method;
+
+/**
+ * Class to manage status and navigation bar tint effects when using KitKat
+ * translucent system UI modes.
+ *
+ */
+public class SystemBarTintManager {
+
+    static {
+        // Android allows a system property to override the presence of the navigation bar.
+        // Used by the emulator.
+        // See https://github.com/android/platform_frameworks_base/blob/master/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java#L1076
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            try {
+                Class c = Class.forName("android.os.SystemProperties");
+                Method m = c.getDeclaredMethod("get", String.class);
+                m.setAccessible(true);
+                sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
+            } catch (Throwable e) {
+                sNavBarOverride = null;
+            }
+        }
+    }
+
+
+    /**
+     * The default system bar tint color value.
+     */
+    public static final int DEFAULT_TINT_COLOR = 0x99000000;
+
+    private static String sNavBarOverride;
+
+    private final SystemBarConfig mConfig;
+    private boolean mStatusBarAvailable;
+    private boolean mNavBarAvailable;
+    private boolean mStatusBarTintEnabled;
+    private boolean mNavBarTintEnabled;
+    private View mStatusBarTintView;
+    private View mNavBarTintView;
+
+    /**
+     * Constructor. Call this in the host activity onCreate method after its
+     * content view has been set. You should always create new instances when
+     * the host activity is recreated.
+     *
+     * @param activity The host activity.
+     */
+    @SuppressLint("ResourceType")
+    @TargetApi(19)
+    public SystemBarTintManager(Activity activity) {
+
+        Window win = activity.getWindow();
+        ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            // check theme attrs
+            int[] attrs = {android.R.attr.windowTranslucentStatus,
+                    android.R.attr.windowTranslucentNavigation};
+            TypedArray a = activity.obtainStyledAttributes(attrs);
+            try {
+                mStatusBarAvailable = a.getBoolean(0, false);
+                mNavBarAvailable = a.getBoolean(1, false);
+            } finally {
+                a.recycle();
+            }
+
+            // check window flags
+            WindowManager.LayoutParams winParams = win.getAttributes();
+            int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
+            if ((winParams.flags & bits) != 0) {
+                mStatusBarAvailable = true;
+            }
+            bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
+            if ((winParams.flags & bits) != 0) {
+                mNavBarAvailable = true;
+            }
+        }
+
+        mConfig = new SystemBarConfig(activity, mStatusBarAvailable, mNavBarAvailable);
+        // device might not have virtual navigation keys
+        if (!mConfig.hasNavigtionBar()) {
+            mNavBarAvailable = false;
+        }
+
+        if (mStatusBarAvailable) {
+            setupStatusBarView(activity, decorViewGroup);
+        }
+        if (mNavBarAvailable) {
+            setupNavBarView(activity, decorViewGroup);
+        }
+
+    }
+
+    /**
+     * Enable tinting of the system status bar.
+     *
+     * If the platform is running Jelly Bean or earlier, or translucent system
+     * UI modes have not been enabled in either the theme or via window flags,
+     * then this method does nothing.
+     *
+     * @param enabled True to enable tinting, false to disable it (default).
+     */
+    public void setStatusBarTintEnabled(boolean enabled) {
+        mStatusBarTintEnabled = enabled;
+        if (mStatusBarAvailable) {
+            mStatusBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
+        }
+    }
+
+    /**
+     * Enable tinting of the system navigation bar.
+     *
+     * If the platform does not have soft navigation keys, is running Jelly Bean
+     * or earlier, or translucent system UI modes have not been enabled in either
+     * the theme or via window flags, then this method does nothing.
+     *
+     * @param enabled True to enable tinting, false to disable it (default).
+     */
+    public void setNavigationBarTintEnabled(boolean enabled) {
+        mNavBarTintEnabled = enabled;
+        if (mNavBarAvailable) {
+            mNavBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
+        }
+    }
+
+    /**
+     * Apply the specified color tint to all system UI bars.
+     *
+     * @param color The color of the background tint.
+     */
+    public void setTintColor(int color) {
+        setStatusBarTintColor(color);
+        setNavigationBarTintColor(color);
+    }
+
+    /**
+     * Apply the specified drawable or color resource to all system UI bars.
+     *
+     * @param res The identifier of the resource.
+     */
+    public void setTintResource(int res) {
+        setStatusBarTintResource(res);
+        setNavigationBarTintResource(res);
+    }
+
+    /**
+     * Apply the specified drawable to all system UI bars.
+     *
+     * @param drawable The drawable to use as the background, or null to remove it.
+     */
+    public void setTintDrawable(Drawable drawable) {
+        setStatusBarTintDrawable(drawable);
+        setNavigationBarTintDrawable(drawable);
+    }
+
+    /**
+     * Apply the specified alpha to all system UI bars.
+     *
+     * @param alpha The alpha to use
+     */
+    public void setTintAlpha(float alpha) {
+        setStatusBarAlpha(alpha);
+        setNavigationBarAlpha(alpha);
+    }
+
+    /**
+     * Apply the specified color tint to the system status bar.
+     *
+     * @param color The color of the background tint.
+     */
+    public void setStatusBarTintColor(int color) {
+        if (mStatusBarAvailable) {
+            mStatusBarTintView.setBackgroundColor(color);
+        }
+    }
+
+    /**
+     * Apply the specified drawable or color resource to the system status bar.
+     *
+     * @param res The identifier of the resource.
+     */
+    public void setStatusBarTintResource(int res) {
+        if (mStatusBarAvailable) {
+            mStatusBarTintView.setBackgroundResource(res);
+        }
+    }
+
+    /**
+     * Apply the specified drawable to the system status bar.
+     *
+     * @param drawable The drawable to use as the background, or null to remove it.
+     */
+    @SuppressWarnings("deprecation")
+    public void setStatusBarTintDrawable(Drawable drawable) {
+        if (mStatusBarAvailable) {
+            mStatusBarTintView.setBackgroundDrawable(drawable);
+        }
+    }
+
+    /**
+     * Apply the specified alpha to the system status bar.
+     *
+     * @param alpha The alpha to use
+     */
+    @TargetApi(11)
+    public void setStatusBarAlpha(float alpha) {
+        if (mStatusBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            mStatusBarTintView.setAlpha(alpha);
+        }
+    }
+
+    /**
+     * Apply the specified color tint to the system navigation bar.
+     *
+     * @param color The color of the background tint.
+     */
+    public void setNavigationBarTintColor(int color) {
+        if (mNavBarAvailable) {
+            mNavBarTintView.setBackgroundColor(color);
+        }
+    }
+
+    /**
+     * Apply the specified drawable or color resource to the system navigation bar.
+     *
+     * @param res The identifier of the resource.
+     */
+    public void setNavigationBarTintResource(int res) {
+        if (mNavBarAvailable) {
+            mNavBarTintView.setBackgroundResource(res);
+        }
+    }
+
+    /**
+     * Apply the specified drawable to the system navigation bar.
+     *
+     * @param drawable The drawable to use as the background, or null to remove it.
+     */
+    @SuppressWarnings("deprecation")
+    public void setNavigationBarTintDrawable(Drawable drawable) {
+        if (mNavBarAvailable) {
+            mNavBarTintView.setBackgroundDrawable(drawable);
+        }
+    }
+
+    /**
+     * Apply the specified alpha to the system navigation bar.
+     *
+     * @param alpha The alpha to use
+     */
+    @TargetApi(11)
+    public void setNavigationBarAlpha(float alpha) {
+        if (mNavBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            mNavBarTintView.setAlpha(alpha);
+        }
+    }
+
+    /**
+     * Get the system bar configuration.
+     *
+     * @return The system bar configuration for the current device configuration.
+     */
+    public SystemBarConfig getConfig() {
+        return mConfig;
+    }
+
+    /**
+     * Is tinting enabled for the system status bar?
+     *
+     * @return True if enabled, False otherwise.
+     */
+    public boolean isStatusBarTintEnabled() {
+        return mStatusBarTintEnabled;
+    }
+
+    /**
+     * Is tinting enabled for the system navigation bar?
+     *
+     * @return True if enabled, False otherwise.
+     */
+    public boolean isNavBarTintEnabled() {
+        return mNavBarTintEnabled;
+    }
+
+    private void setupStatusBarView(Context context, ViewGroup decorViewGroup) {
+        mStatusBarTintView = new View(context);
+        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight());
+        params.gravity = Gravity.TOP;
+        if (mNavBarAvailable && !mConfig.isNavigationAtBottom()) {
+            params.rightMargin = mConfig.getNavigationBarWidth();
+        }
+        mStatusBarTintView.setLayoutParams(params);
+        mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);
+        mStatusBarTintView.setVisibility(View.GONE);
+        decorViewGroup.addView(mStatusBarTintView);
+    }
+
+    private void setupNavBarView(Context context, ViewGroup decorViewGroup) {
+        mNavBarTintView = new View(context);
+        LayoutParams params;
+        if (mConfig.isNavigationAtBottom()) {
+            params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getNavigationBarHeight());
+            params.gravity = Gravity.BOTTOM;
+        } else {
+            params = new LayoutParams(mConfig.getNavigationBarWidth(), LayoutParams.MATCH_PARENT);
+            params.gravity = Gravity.RIGHT;
+        }
+        mNavBarTintView.setLayoutParams(params);
+        mNavBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);
+        mNavBarTintView.setVisibility(View.GONE);
+        decorViewGroup.addView(mNavBarTintView);
+    }
+
+    /**
+     * Class which describes system bar sizing and other characteristics for the current
+     * device configuration.
+     *
+     */
+    public static class SystemBarConfig {
+
+        private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";
+        private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height";
+        private static final String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = "navigation_bar_height_landscape";
+        private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width";
+        private static final String SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar";
+
+        private final boolean mTranslucentStatusBar;
+        private final boolean mTranslucentNavBar;
+        private final int mStatusBarHeight;
+        private final int mActionBarHeight;
+        private final boolean mHasNavigationBar;
+        private final int mNavigationBarHeight;
+        private final int mNavigationBarWidth;
+        private final boolean mInPortrait;
+        private final float mSmallestWidthDp;
+
+        private SystemBarConfig(Activity activity, boolean translucentStatusBar, boolean traslucentNavBar) {
+            Resources res = activity.getResources();
+            mInPortrait = (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
+            mSmallestWidthDp = getSmallestWidthDp(activity);
+            mStatusBarHeight = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME);
+            mActionBarHeight = getActionBarHeight(activity);
+            mNavigationBarHeight = getNavigationBarHeight(activity);
+            mNavigationBarWidth = getNavigationBarWidth(activity);
+            mHasNavigationBar = (mNavigationBarHeight > 0);
+            mTranslucentStatusBar = translucentStatusBar;
+            mTranslucentNavBar = traslucentNavBar;
+        }
+
+        @TargetApi(14)
+        private int getActionBarHeight(Context context) {
+            int result = 0;
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+                TypedValue tv = new TypedValue();
+                context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);
+                result = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
+            }
+            return result;
+        }
+
+        @TargetApi(14)
+        private int getNavigationBarHeight(Context context) {
+            Resources res = context.getResources();
+            int result = 0;
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+                if (hasNavBar(context)) {
+                    String key;
+                    if (mInPortrait) {
+                        key = NAV_BAR_HEIGHT_RES_NAME;
+                    } else {
+                        key = NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME;
+                    }
+                    return getInternalDimensionSize(res, key);
+                }
+            }
+            return result;
+        }
+
+        @TargetApi(14)
+        private int getNavigationBarWidth(Context context) {
+            Resources res = context.getResources();
+            int result = 0;
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+                if (hasNavBar(context)) {
+                    return getInternalDimensionSize(res, NAV_BAR_WIDTH_RES_NAME);
+                }
+            }
+            return result;
+        }
+
+        @TargetApi(14)
+        private boolean hasNavBar(Context context) {
+            Resources res = context.getResources();
+            int resourceId = res.getIdentifier(SHOW_NAV_BAR_RES_NAME, "bool", "android");
+            if (resourceId != 0) {
+                boolean hasNav = res.getBoolean(resourceId);
+                // check override flag (see static block)
+                if ("1".equals(sNavBarOverride)) {
+                    hasNav = false;
+                } else if ("0".equals(sNavBarOverride)) {
+                    hasNav = true;
+                }
+                return hasNav;
+            } else { // fallback
+                return !ViewConfiguration.get(context).hasPermanentMenuKey();
+            }
+        }
+
+        private int getInternalDimensionSize(Resources res, String key) {
+            int result = 0;
+            int resourceId = res.getIdentifier(key, "dimen", "android");
+            if (resourceId > 0) {
+                result = res.getDimensionPixelSize(resourceId);
+            }
+            return result;
+        }
+
+        @SuppressLint("NewApi")
+        private float getSmallestWidthDp(Activity activity) {
+            DisplayMetrics metrics = new DisplayMetrics();
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+                activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
+            } else {
+                // TODO this is not correct, but we don't really care pre-kitkat
+                activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
+            }
+            float widthDp = metrics.widthPixels / metrics.density;
+            float heightDp = metrics.heightPixels / metrics.density;
+            return Math.min(widthDp, heightDp);
+        }
+
+        /**
+         * Should a navigation bar appear at the bottom of the screen in the current
+         * device configuration? A navigation bar may appear on the right side of
+         * the screen in certain configurations.
+         *
+         * @return True if navigation should appear at the bottom of the screen, False otherwise.
+         */
+        public boolean isNavigationAtBottom() {
+            return (mSmallestWidthDp >= 600 || mInPortrait);
+        }
+
+        /**
+         * Get the height of the system status bar.
+         *
+         * @return The height of the status bar (in pixels).
+         */
+        public int getStatusBarHeight() {
+            return mStatusBarHeight;
+        }
+
+        /**
+         * Get the height of the action bar.
+         *
+         * @return The height of the action bar (in pixels).
+         */
+        public int getActionBarHeight() {
+            return mActionBarHeight;
+        }
+
+        /**
+         * Does this device have a system navigation bar?
+         *
+         * @return True if this device uses soft key navigation, False otherwise.
+         */
+        public boolean hasNavigtionBar() {
+            return mHasNavigationBar;
+        }
+
+        /**
+         * Get the height of the system navigation bar.
+         *
+         * @return The height of the navigation bar (in pixels). If the device does not have
+         * soft navigation keys, this will always return 0.
+         */
+        public int getNavigationBarHeight() {
+            return mNavigationBarHeight;
+        }
+
+        /**
+         * Get the width of the system navigation bar when it is placed vertically on the screen.
+         *
+         * @return The width of the navigation bar (in pixels). If the device does not have
+         * soft navigation keys, this will always return 0.
+         */
+        public int getNavigationBarWidth() {
+            return mNavigationBarWidth;
+        }
+
+        /**
+         * Get the layout inset for any system UI that appears at the top of the screen.
+         *
+         * @param withActionBar True to include the height of the action bar, False otherwise.
+         * @return The layout inset (in pixels).
+         */
+        public int getPixelInsetTop(boolean withActionBar) {
+            return (mTranslucentStatusBar ? mStatusBarHeight : 0) + (withActionBar ? mActionBarHeight : 0);
+        }
+
+        /**
+         * Get the layout inset for any system UI that appears at the bottom of the screen.
+         *
+         * @return The layout inset (in pixels).
+         */
+        public int getPixelInsetBottom() {
+            if (mTranslucentNavBar && isNavigationAtBottom()) {
+                return mNavigationBarHeight;
+            } else {
+                return 0;
+            }
+        }
+
+        /**
+         * Get the layout inset for any system UI that appears at the right of the screen.
+         *
+         * @return The layout inset (in pixels).
+         */
+        public int getPixelInsetRight() {
+            if (mTranslucentNavBar && !isNavigationAtBottom()) {
+                return mNavigationBarWidth;
+            } else {
+                return 0;
+            }
+        }
+
+    }
+
+}

+ 0 - 145
baselibrary/src/main/java/com/webrain/baselibrary/utils/OSUtil.java

@@ -1,145 +0,0 @@
-package com.webrain.baselibrary.utils;
-
-import android.os.Environment;
-import android.text.TextUtils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-public class OSUtil {
-    //MIUI标识
-    private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
-    private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
-    private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
-
-    //EMUI标识
-    private static final String KEY_EMUI_VERSION_CODE = "ro.build.version.emui";
-    private static final String KEY_EMUI_API_LEVEL = "ro.build.hw_emui_api_level";
-    private static final String KEY_EMUI_CONFIG_HW_SYS_VERSION = "ro.confg.hw_systemversion";
-
-    //Flyme标识
-    private static final String KEY_FLYME_ID_FALG_KEY = "ro.build.display.id";
-    private static final String KEY_FLYME_ID_FALG_VALUE_KEYWORD = "Flyme";
-    private static final String KEY_FLYME_ICON_FALG = "persist.sys.use.flyme.icon";
-    private static final String KEY_FLYME_SETUP_FALG = "ro.meizu.setupwizard.flyme";
-    private static final String KEY_FLYME_PUBLISH_FALG = "ro.flyme.published";
-
-    /**
-     * 是否是Flyme系统
-     * @return
-     */
-    public static boolean isFlyme() {
-        if(isPropertiesExist(KEY_FLYME_ICON_FALG, KEY_FLYME_SETUP_FALG, KEY_FLYME_PUBLISH_FALG)) {
-            return true;
-        }
-        try {
-            BuildProperties buildProperties = BuildProperties.newInstance();
-            if(buildProperties.containsKey(KEY_FLYME_ID_FALG_KEY)) {
-                String romName = buildProperties.getProperty(KEY_FLYME_ID_FALG_KEY);
-                if (!TextUtils.isEmpty(romName) && romName.contains(KEY_FLYME_ID_FALG_VALUE_KEYWORD)) {
-                    return true;
-                }
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return false;
-    }
-
-    /**
-     * 是否是EMUI系统
-     * @return
-     */
-    public static boolean isEMUI() {
-        return isPropertiesExist(KEY_EMUI_VERSION_CODE, KEY_EMUI_API_LEVEL,
-                KEY_EMUI_CONFIG_HW_SYS_VERSION);
-    }
-
-    /**
-     * 是否是MIUI系统
-     * @return
-     */
-    public static boolean isMIUI() {
-        return isPropertiesExist(KEY_MIUI_VERSION_CODE, KEY_MIUI_VERSION_NAME,
-                KEY_MIUI_INTERNAL_STORAGE);
-    }
-
-    private static boolean isPropertiesExist(String... keys) {
-        if (keys == null || keys.length == 0) {
-            return false;
-        }
-        try {
-            BuildProperties properties = BuildProperties.newInstance();
-            for (String key : keys) {
-                String value = properties.getProperty(key);
-                if (value != null)
-                    return true;
-            }
-            return false;
-        } catch (IOException e) {
-            return false;
-        }
-    }
-
-    private static final class BuildProperties {
-
-        private final Properties properties;
-
-        private BuildProperties() throws IOException {
-            properties = new Properties();
-            // 读取系统配置信息build.prop类
-            properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build" +
-                    ".prop")));
-        }
-
-        public boolean containsKey(final Object key) {
-            return properties.containsKey(key);
-        }
-
-        public boolean containsValue(final Object value) {
-            return properties.containsValue(value);
-        }
-
-        public Set<Map.Entry<Object, Object>> entrySet() {
-            return properties.entrySet();
-        }
-
-        public String getProperty(final String name) {
-            return properties.getProperty(name);
-        }
-
-        public String getProperty(final String name, final String defaultValue) {
-            return properties.getProperty(name, defaultValue);
-        }
-
-        public boolean isEmpty() {
-            return properties.isEmpty();
-        }
-
-        public Enumeration<Object> keys() {
-            return properties.keys();
-        }
-
-        public Set<Object> keySet() {
-            return properties.keySet();
-        }
-
-        public int size() {
-            return properties.size();
-        }
-
-        public Collection<Object> values() {
-            return properties.values();
-        }
-
-        public static BuildProperties newInstance() throws IOException {
-            return new BuildProperties();
-        }
-    }
-}

+ 119 - 0
baselibrary/src/main/java/com/webrain/baselibrary/utils/OSUtils.java

@@ -0,0 +1,119 @@
+package com.webrain.baselibrary.utils;
+
+import android.os.Build;
+import android.text.TextUtils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class OSUtils {
+
+    public static final String ROM_MIUI = "MIUI";
+    public static final String ROM_EMUI = "EMUI";
+    public static final String ROM_FLYME = "FLYME";
+    public static final String ROM_OPPO = "OPPO";
+    public static final String ROM_SMARTISAN = "SMARTISAN";
+    public static final String ROM_VIVO = "VIVO";
+    public static final String ROM_QIKU = "QIKU";
+
+    private static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name";
+    private static final String KEY_VERSION_EMUI = "ro.build.version.emui";
+    private static final String KEY_VERSION_OPPO = "ro.build.version.opporom";
+    private static final String KEY_VERSION_SMARTISAN = "ro.smartisan.version";
+    private static final String KEY_VERSION_VIVO = "ro.vivo.os.version";
+
+    private static String sName;
+    private static String sVersion;
+
+    public static boolean isEmui() {
+        return check(ROM_EMUI);
+    }
+
+    public static boolean isMiui() {
+        return check(ROM_MIUI);
+    }
+
+    public static boolean isVivo() {
+        return check(ROM_VIVO);
+    }
+
+    public static boolean isOppo() {
+        return check(ROM_OPPO);
+    }
+
+    public static boolean isFlyme() {
+        return check(ROM_FLYME);
+    }
+
+    public static boolean is360() {
+        return check(ROM_QIKU) || check("360");
+    }
+
+    public static boolean isSmartisan() {
+        return check(ROM_SMARTISAN);
+    }
+
+    public static String getName() {
+        if (sName == null) {
+            check("");
+        }
+        return sName;
+    }
+
+    public static String getVersion() {
+        if (sVersion == null) {
+            check("");
+        }
+        return sVersion;
+    }
+
+    public static boolean check(String rom) {
+        if (sName != null) {
+            return sName.equals(rom);
+        }
+
+        if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_MIUI))) {
+            sName = ROM_MIUI;
+        } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_EMUI))) {
+            sName = ROM_EMUI;
+        } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_OPPO))) {
+            sName = ROM_OPPO;
+        } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_VIVO))) {
+            sName = ROM_VIVO;
+        } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_SMARTISAN))) {
+            sName = ROM_SMARTISAN;
+        } else {
+            sVersion = Build.DISPLAY;
+            if (sVersion.toUpperCase().contains(ROM_FLYME)) {
+                sName = ROM_FLYME;
+            } else {
+                sVersion = Build.UNKNOWN;
+                sName = Build.MANUFACTURER.toUpperCase();
+            }
+        }
+        return sName.equals(rom);
+    }
+
+    public static String getProp(String name) {
+        String line = null;
+        BufferedReader input = null;
+        try {
+            Process p = Runtime.getRuntime().exec("getprop " + name);
+            input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
+            line = input.readLine();
+            input.close();
+        } catch (IOException ex) {
+            return null;
+        } finally {
+            if (input != null) {
+                try {
+                    input.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return line;
+    }
+}