自定义UI——沉浸式状态栏

从Android4.4开始出现相关API之后,沉浸式状态栏算是我们APP的标配了,随着Android的API的优化,5.0又是一个分水岭。现整理了一下状态栏导航栏是否存在以及颜色设置,高度获取的相关方法工具类,以便后续之需。

package com.demo.statusdemo;

import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

/**
 * Created by yueban on 2018/7/30.
 * 状态栏工具类
 */

public class StatusUtils {


    private StatusUtils() {
    }

    private static class Holder {
        private static StatusUtils instance = new StatusUtils();
    }

    public static StatusUtils getInstance() {
        return Holder.instance;
    }

    /**
     * 设置状态栏颜色
     */
    public void setStatusStyle(Activity activity, int color) {
        //设置 paddingTop
        ViewGroup rootView = activity.getWindow().getDecorView().findViewById(android.R.id.content);
        rootView.setPadding(0, getStatusHeight(activity), 0, 0);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //5.0 以上直接设置状态栏颜色
            activity.getWindow().setStatusBarColor(color);
        } else {
            //根布局添加占位状态栏
            ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
            View statusBarView = new View(activity);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusHeight(activity));
            statusBarView.setBackgroundColor(color);
            decorView.addView(statusBarView, lp);
        }

    }

    /**
     * 针对5.0以上 Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP
     */

    public void setStatusColor(Activity context) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            context.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            context.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }

    }

    /**
     * 针对4.4-5.0Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
     */
    public void setStatusColor(Activity context, View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            //获取状态栏的高度给标题控件设置padding
            int statusHeight = getStatusHeight(context);
            view.setPadding(0, view.getPaddingTop() + statusHeight, 0, 0);
        }
    }

    /**
     * 设置导航栏的颜色 一般华为手机
     *
     * @param context
     * @param bottomView
     * @param styleColor
     */
    public void setNavigationBarStyle(Activity context, View bottomView, int styleColor) {
        ViewGroup.LayoutParams params = bottomView.getLayoutParams();
        params.height = getNavigationHeight(context);
        bottomView.setLayoutParams(params);
        bottomView.setBackgroundColor(styleColor);
    }

    /**
     * 是否存在导航栏
     *
     * @param context
     * @return
     */
    public boolean isHasNavigation(Activity context) {
        Display display = context.getWindowManager().getDefaultDisplay();
        DisplayMetrics realDisplay = new DisplayMetrics();
        DisplayMetrics showDisplay = new DisplayMetrics();
        display.getRealMetrics(realDisplay);
        display.getMetrics(showDisplay);
        //为了防止横屏  分别取宽高差 有一个大于0 就是存在导航栏
        int realHeight = realDisplay.heightPixels;
        int realWidth = realDisplay.widthPixels;
        int height = showDisplay.heightPixels;
        int width = showDisplay.widthPixels;
        return (realHeight - height > 0) || (realWidth - width > 0);
    }

    /**
     * 获取状态栏高度
     *
     * @param context
     * @return
     */
    private int getStatusHeight(Context context) {
        //通过反射
        int height = -1;
        try {
            Class clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();//获取对象
            String statusBarHeight = clazz.getField("status_bar_height").get(object).toString();
            int statusHeight = Integer.parseInt(statusBarHeight);
            height = context.getResources().getDimensionPixelSize(statusHeight);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return height;
    }

    private int getNavigationHeight(Context context) {
        int height = -1;
        try {
            Class clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            String heightStr = clazz.getField("navigation_bar_height").get(object).toString();
            height = Integer.parseInt(heightStr);
            height = context.getResources().getDimensionPixelSize(height);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return height;
    }
}

在4.4-5.0在设置的时候需要在Style.xml文件中添加以下代码:


        true
        true

虽然后还有占位View,设置theme等方式,但是综合起来还是设置padding的方式灵活性大方便。

你可能感兴趣的:(UI)