安卓状态栏
package com.common.utils;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.IntRange;
import android.support.v4.widget.DrawerLayout;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.LinearLayout;
import com.common.R;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
-
@desc: 屏幕相关工具类
-
@author: Leo
-
@date: 2016/09/26
*/
public class ScreenUtils {private ScreenUtils() {
throw new UnsupportedOperationException(“error…”);
}/**
- 获取屏幕的宽度px
- @param context 上下文
- @return 屏幕宽px
*/
public static int getScreenWidth(Context context) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸
windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高
return outMetrics.widthPixels;
}
/**
- 获取屏幕的高度px
- @param context 上下文
- @return 屏幕高px
*/
public static int getScreenHeight(Context context) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸
windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高
return outMetrics.heightPixels;
}
/**
- 获取屏幕的px
- @param activity 上下文
- @return 屏幕高px
*/
public static DisplayMetrics getScreenPix(Activity activity) {
DisplayMetrics displaysMetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(displaysMetrics);
return displaysMetrics;
}
/**
- 设置透明状态栏(api大于19方可使用)
-
可在Activity的onCreat()中调用
-
需在顶部控件布局中加入以下属性让内容出现在状态栏之下
-
android:clipToPadding="true"
-
android:fitsSystemWindows="true"
- @param activity activity
*/
public static void setTransparentStatusBar(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明状态栏
activity.getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS);
//透明导航栏
activity.getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}
/**
- 隐藏状态栏
-
也就是设置全屏,一定要在setContentView之前调用,否则报错
-
此方法Activity可以继承AppCompatActivity
-
启动的时候状态栏会显示一下再隐藏,比如QQ的欢迎界面
-
在配置文件中Activity加属性android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
-
如加了以上配置Activity不能继承AppCompatActivity,会报错
- @param activity activity
*/
public static void hideStatusBar(Activity activity) {
activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
activity.getWindow().setFlags(LayoutParams.FLAG_FULLSCREEN,
LayoutParams.FLAG_FULLSCREEN);
}
/**
- 获取状态栏高度
- @param context 上下文
- @return 状态栏高度
*/
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;
}
/**
- 判断状态栏是否存在
- @param activity activity
- @return {@code true}: 存在
{@code false}: 不存在
*/
public static boolean isStatusBarExists(Activity activity) {
LayoutParams params = activity.getWindow().getAttributes();
return (params.flags & LayoutParams.FLAG_FULLSCREEN) != LayoutParams.FLAG_FULLSCREEN;
}
/**
- 获取ActionBar高度
- @param activity activity
- @return ActionBar高度
*/
public static int getActionBarHeight(Activity activity) {
TypedValue tv = new TypedValue();
if (activity.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
return TypedValue.complexToDimensionPixelSize(tv.data, activity.getResources().getDisplayMetrics());
}
return 0;
}
/**
- 设置屏幕为横屏
-
还有一种就是在Activity中加属性android:screenOrientation="landscape"
-
不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
-
设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
-
设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"(4.0以上必须带最后一个参数)时
- 切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
- @param activity activity
*/
public static void setLandscape(Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
/**
- 获取当前屏幕截图,包含状态栏
- @param activity activity
- @return Bitmap
*/
public static Bitmap captureWithStatusBar(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
int width = getScreenWidth(activity);
int height = getScreenHeight(activity);
Bitmap bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
view.destroyDrawingCache();
return bp;
}
/**
- 获取当前屏幕截图,不包含状态栏
-
需要用到上面获取状态栏高度getStatusBarHeight的方法
- @param activity activity
- @return Bitmap
*/
public static Bitmap captureWithoutStatusBar(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
int statusBarHeight = getStatusBarHeight(activity);
int width = getScreenWidth(activity);
int height = getScreenHeight(activity);
Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);
view.destroyDrawingCache();
return bp;
}
/**
- 判断是否锁屏
- @param context 上下文
- @return {@code true}: 是
{@code false}: 否
*/
public static boolean isScreenLock(Context context) {
KeyguardManager km = (KeyguardManager) context
.getSystemService(Context.KEYGUARD_SERVICE);
return km.inKeyguardRestrictedInputMode();
}
/**
-
获取状态栏高度 默认4.4以下返回状态栏高度为0
-
@param context con
-
@return 状态栏高度
*/
public static int getStatusHeight(Context context)
{
int statusBarHeight = 0;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// 获取status_bar_height资源的ID
int resourceId = context.getResources().getIdentifier(“status_bar_height”, “dimen”, “android”);
if (resourceId > 0) {
// 根据资源ID获取响应的尺寸值
statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
}
}return statusBarHeight;
}
/**
-
设置状态栏图标为深色和魅族特定的文字风格
-
可以用来判断是否为Flyme用户
-
@param window 需要设置的窗口
-
@param dark 是否把状态栏字体及图标颜色设置为深色
-
@return boolean 成功执行返回true
*/
private static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
if (window != null) {
try {
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);
result = true;
} catch (Exception e) {}
}
return result;
}
/**
-
设置状态栏字体图标为深色,需要MIUIV6以上
-
@param window 需要设置的窗口
-
@param dark 是否把状态栏字体及图标颜色设置为深色
-
@return boolean 成功执行返回true
*/
private static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
if (window != null) {
Class clazz = window.getClass();
try {
int darkModeFlag = 0;
Class layoutParams = Class.forName(“android.view.MiuiWindowManager$LayoutParams”);
Field field = layoutParams.getField(“EXTRA_FLAG_STATUS_BAR_DARK_MODE”);
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod(“setExtraFlags”, int.class, int.class);
if (dark) {
extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体
} else {
extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
}
result = true;
} catch (Exception e) {}
}
return result;
}
/**
-
状态栏透明
-
未实现虚拟按钮的隐藏,界面覆盖虚拟按钮,
-
虚拟按钮可响应事件暂未解决
-
@param activity activity
*/
public static void translateStatusBar(Activity activity)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
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.TRANSPARENT);} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WindowManager.LayoutParams localLayoutParams = activity.getWindow().getAttributes();
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags;
}
}
/**
- 状态栏透明,并设置状态栏字体颜色为深色
- @param activity
*/
public static void translateSetTextColerStatusBar(Activity activity)
{
translateStatusBar(activity);
setTextColorStatusBar(activity, true);
}
/**
-
设置状态栏字体颜色
-
@param activity activity
-
@param isDark isdark
*/
public static void setTextColorStatusBar(Activity activity, boolean isDark)
{
FlymeSetStatusBarLightMode(activity.getWindow(), isDark);
MIUISetStatusBarLightMode(activity.getWindow(), isDark);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isDark) {//6.0
if (isDark) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
}
}
/****** 状态栏处理 START ******/
private static final int FAKE_TRANSLUCENT_VIEW_ID = R.id.statusbarutil_translucent_view;
private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.statusbarutil_fake_status_bar_view;
public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color,
@IntRange(from = 0, to = 255) int statusBarAlpha) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
} else {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
// 生成一个状态栏大小的矩形
// 添加 statusBarView 到布局中
ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
if (fakeStatusBarView != null) {
if (fakeStatusBarView.getVisibility() == View.GONE) {
fakeStatusBarView.setVisibility(View.VISIBLE);
}
fakeStatusBarView.setBackgroundColor(color);
} else {
contentLayout.addView(createStatusBarView(activity, color), 0);
}
// 内容布局不是 LinearLayout 时,设置padding top
if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
contentLayout.getChildAt(1)
.setPadding(contentLayout.getPaddingLeft(), getStatusBarHeight(activity) + contentLayout.getPaddingTop(),
contentLayout.getPaddingRight(), contentLayout.getPaddingBottom());
}
// 设置属性
setDrawerLayoutProperty(drawerLayout, contentLayout);
addTranslucentView(activity, statusBarAlpha);
}public static void setColorForDrawerLayout(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
} else {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
addTranslucentView(activity, statusBarAlpha);
}/**
- 添加半透明矩形条
- @param activity 需要设置的 activity
- @param statusBarAlpha 透明值
*/
private static void addTranslucentView(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {
ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
View fakeTranslucentView = contentView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);
if (fakeTranslucentView != null) {
if (fakeTranslucentView.getVisibility() == View.GONE) {
fakeTranslucentView.setVisibility(View.VISIBLE);
}
fakeTranslucentView.setBackgroundColor(Color.argb(statusBarAlpha, 0, 0, 0));
} else {
contentView.addView(createTranslucentStatusBarView(activity, statusBarAlpha));
}
}
/**
- 创建半透明矩形 View
- @param alpha 透明值
- @return 半透明 View
*/
private static View createTranslucentStatusBarView(Activity activity, int alpha) {
// 绘制一个和状态栏一样高的矩形
View statusBarView = new View(activity);
LinearLayout.LayoutParams params =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
statusBarView.setLayoutParams(params);
statusBarView.setBackgroundColor(Color.argb(alpha, 0, 0, 0));
statusBarView.setId(FAKE_TRANSLUCENT_VIEW_ID);
return statusBarView;
}
/**
- 设置 DrawerLayout 属性
- @param drawerLayout DrawerLayout
- @param drawerLayoutContentLayout DrawerLayout 的内容布局
*/
private static void setDrawerLayoutProperty(DrawerLayout drawerLayout, ViewGroup drawerLayoutContentLayout) {
ViewGroup drawer = (ViewGroup) drawerLayout.getChildAt(1);
drawerLayout.setFitsSystemWindows(false);
drawerLayoutContentLayout.setFitsSystemWindows(false);
drawerLayoutContentLayout.setClipToPadding(true);
drawer.setFitsSystemWindows(false);
}
/**
- 生成一个和状态栏大小相同的彩色矩形条
- @param activity 需要设置的 activity
- @param color 状态栏颜色值
- @return 状态栏矩形条
*/
private static View createStatusBarView(Activity activity, @ColorInt int color) {
return createStatusBarView(activity, color, 0);
}
/**
- 生成一个和状态栏大小相同的半透明矩形条
- @param activity 需要设置的activity
- @param color 状态栏颜色值
- @param alpha 透明值
- @return 状态栏矩形条
*/
private static View createStatusBarView(Activity activity, @ColorInt int color, int alpha) {
// 绘制一个和状态栏一样高的矩形
View statusBarView = new View(activity);
LinearLayout.LayoutParams params =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
statusBarView.setLayoutParams(params);
statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));
statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
return statusBarView;
}
/**
- 计算状态栏颜色
- @param color color值
- @param alpha alpha值
- @return 最终的状态栏颜色
/
private static int calculateStatusColor(@ColorInt int color, int alpha) {
if (alpha == 0) {
return color;
}
float a = 1 - alpha / 255f;
int red = color >> 16 & 0xff;
int green = color >> 8 & 0xff;
int blue = color & 0xff;
red = (int) (red * a + 0.5);
green = (int) (green * a + 0.5);
blue = (int) (blue * a + 0.5);
return 0xff << 24 | red << 16 | green << 8 | blue;
}
/***** 状态栏处理 END ******/
}