java沉浸状态栏代码,实现4.4以上的状态栏沉浸和变色

这篇博客主要介绍了如何在Android应用中实现状态栏的沉浸效果,并针对不同版本的Android系统,如4.4、5.0、6.0等进行适配。包括设置状态栏颜色、透明度以及在魅族Flyme和小米MIUI系统中改变状态栏字体颜色的方法。同时提供了相关工具类和布局文件的代码示例。
摘要由CSDN通过智能技术生成

2d989dc6e2a1

Paste_Image.png

2d989dc6e2a1

Paste_Image.png

2d989dc6e2a1

配色

@color/darkGray

@color/colorPrimaryDark

@color/colorAccent

布局

activity_main.xml

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:id="@+id/toolbar_holder"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="?attr/colorPrimary">

android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"

app:popupTheme="@style/ThemeOverlay.AppCompat.Light"

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="?attr/actionBarSize"

android:background="?attr/colorPrimary"

android:elevation="4dp"/>

代码

HomeActivity.java

public class HomeActivity extends AppCompatActivity {

@InjectView(R.id.toolbar) Toolbar mToolbar;

@InjectView(R.id.toolbar_holder) RelativeLayout mToolbarHolder;

@Override protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_home);

ButterKnife.inject(this);

LollipopUtils.setStatusbarColor(this, mToolbarHolder);

}

工具类: LollipopUtils.java

package com.example.hante.newnetpas.home.Util;

import android.app.Activity;

import android.content.Context;

import android.os.Build;

import android.util.Log;

import android.view.View;

import android.view.Window;

import android.view.WindowManager;

public class LollipopUtils {

public static int getStatusBarHeight(Context context) {

Context appContext = context.getApplicationContext();

int result = 0;

int resourceId =

appContext.getResources().getIdentifier("status_bar_height", "dimen", "android");

if (resourceId > 0) {

result = appContext.getResources().getDimensionPixelSize(resourceId);

}

Log.d("ScreenUtils", result + "");

return result;

}

public static void setStatusbarColor(Activity activity, View view) {

//对于4.4以上 的设备,只需要在style.xml中设置colorPrimaryDark即可

//对于4.4的设备,如下设置padding即可,颜色同样在style.xml中配置

Window w = activity.getWindow();

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {

w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,

WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

int statusBarHeight = getStatusBarHeight(activity);

view.setPadding(0, statusBarHeight, 0, 0);

return;

}

}

}

flyme 魅族 状态栏适配 translucent

activity_main.xml

xmlns:tools="http://schemas.android.com/tools"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:orientation="vertical"

android:layout_height="match_parent"

tools:context=".MainActivity">

android:fitsSystemWindows="true"

android:clipToPadding="false"

android:text="@string/hello_world"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

Raw FlyMeUtils.java

public class FlyMeUtils {

/**

* setDarkStatusBar on FlyMe

* 设置状态栏字体为暗色 仅魅族有效

*/

public static void setDarkStatusBar(Activity activity, boolean isDark) {

WindowManager.LayoutParams lp = activity.getWindow().getAttributes();

try {

Class> instance = Class.forName("android.view.WindowManager$LayoutParams");

int value = instance.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON").getInt(lp);

Field field = instance.getDeclaredField("meizuFlags");

field.setAccessible(true);

int origin = field.getInt(lp);

if (isDark) {

field.set(lp, origin | value);

} else {

field.set(lp, (~value) & origin);

}

} catch (Exception e) {

e.printStackTrace();

}

}

}```

Raw LollipopUtils.java

public class LollipopUtils {

public static int getStatusBarHeight(Context context) {

Context appContext = context.getApplicationContext();

int result = 0;

int resourceId =

appContext.getResources().getIdentifier("status_bar_height", "dimen", "android");

if (resourceId > 0) {

result = appContext.getResources().getDimensionPixelSize(resourceId);

}

Log.d("ScreenUtils", result + "");

return result;

}

public static void setStatusbarColor(Activity activity, View view) {

//对于Lollipop 的设备,只需要在style.xml中设置colorPrimaryDark即可

//对于4.4的设备,如下设置padding即可,颜色同样在style.xml中配置

Window w = activity.getWindow();

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {

w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,

WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

view.setPadding(0, getStatusBarHeight(activity), 0, 0);

}

}

}

Raw MainActivity.java

public class MainActivity extends AppCompatActivity {

@Bind(R.id.toolbar) Toolbar toolbar;

@Bind(R.id.toolbar_holder) RelativeLayout toolbarHolder;

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

ButterKnife.bind(this);

setTheme(android.R.style.Theme_DeviceDefault_Light_NoActionBar);

FlyMeUtils.setDarkStatusBar(this, true);

LollipopUtils.setStatusbarColor(this, toolbarHolder);

toolbar.setTitle("Hello BugMe!");

//setTranslucentStatusBar(true);

}

}```

Raw toolbar.xml

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:id="@+id/toolbar_holder"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="?attr/colorPrimaryDark">

android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"

app:popupTheme="@style/ThemeOverlay.AppCompat.Light"

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="?attr/actionBarSize"

android:background="?attr/colorPrimary"

android:elevation="4dp"/>

处理4.4以上的沉浸

处理6.0以上的沉浸与字体颜色,5.0只可以处理沉浸而不能改字体颜色(故不建议用白色背景)

调用私有API处理小米魅族的状态栏字体颜色

获取状态栏高度

状态栏背景取决于你的Toolbar

另外提供Toolbar的高度自动适配作为参考

截图

2d989dc6e2a1

方法一:状态栏的使用

在Activity中设置如下即可,注意xml/style中不用写任何关于状态栏的属性(特别是fitsSystemWindows这个属性),直接拿来用就可以

@Override protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

StatusbarUtils.from(this)

//沉浸状态栏

.setTransparentStatusbar(true)

//白底黑字状态栏

.setLightStatusBar(true)

//设置toolbar,actionbar等view

.setActionbarView(mNavigationBar)

.process();

}

方法二:view的单独使用

下面代码是在4.4以上自动增长了状态栏的高度,需要在xml中加入windowIsTranslucent属性即可。

//某个View的构造函数中的调用

public void setFitTranslucent(final boolean translucent) {

post(new Runnable() {

@Override public void run() {

if (StatusbarUtils.isLessKitkat() || !translucent) {

return;

}

int height = StatusbarUtils.getStatusBarOffsetPx(getContext());

setPadding(getPaddingLeft(), height + getPaddingTop(), getPaddingRight(), getPaddingBottom());

getLayoutParams().height += height;

}

});

}

工具类

package com.github.miao1007.animewallpaper.utils;

import android.annotation.TargetApi;

import android.app.Activity;

import android.app.Dialog;

import android.content.Context;

import android.graphics.Color;

import android.os.Build;

import android.support.annotation.IntRange;

import android.support.annotation.NonNull;

import android.support.annotation.Nullable;

import android.view.View;

import android.view.Window;

import android.view.WindowManager;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

/**

* Created by leon on 10/31/15.

*/

public final class StatusBarUtils {

private final boolean lightStatusBar;

//透明且背景不占用控件的statusbar,这里估且叫做沉浸

private final boolean transparentStatusBar;

private final boolean transparentNavigationbar;

private final Window window;

private final View actionBarView;

private final int current = Build.VERSION.SDK_INT;

private StatusBarUtils(Window window, boolean lightStatusBar, boolean transparentStatusBar,

boolean transparentNavigationbar, View actionBarView) {

this.lightStatusBar = lightStatusBar;

this.transparentStatusBar = transparentStatusBar;

this.window = window;

this.transparentNavigationbar = transparentNavigationbar;

this.actionBarView = actionBarView;

}

public static boolean isLessKitkat() {

return Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT;

}

public static Builder from(Activity activity) {

return new Builder().setWindow(activity);

}

public static Builder from(Dialog dialog) {

return new Builder().setWindow(dialog);

}

public static Builder from(Window window) {

return new Builder().setWindow(window);

}

/**

* Default status dp = 24 or 25

* mhdpi = dp * 1

* hdpi = dp * 1.5

* xhdpi = dp * 2

* xxhdpi = dp * 3

* eg : 1920x1080, xxhdpi, => status/all = 25/640(dp) = 75/1080(px)

*

* don't forget toolbar's dp = 48

*

* @return px

*/

@IntRange(from = 0, to = 75) public static int getStatusBarOffsetPx(Context context) {

if (isLessKitkat()) {

return 0;

}

Context appContext = context.getApplicationContext();

int result = 0;

int resourceId =

appContext.getResources().getIdentifier("status_bar_height", "dimen", "android");

if (resourceId > 0) {

result = appContext.getResources().getDimensionPixelSize(resourceId);

}

return result;

}

@IntRange(from = 0, to = 75) public static int getNavigationBarOffsetPx(Context context) {

if (isLessKitkat()) {

return 0;

}

Context appContext = context.getApplicationContext();

int result = 0;

int resourceId =

appContext.getResources().getIdentifier("navigation_bar_height", "dimen", "android");

if (resourceId > 0) {

result = appContext.getResources().getDimensionPixelSize(resourceId);

}

return result;

}

private void processActionBar(final View v) {

if (v == null || !transparentStatusBar || isLessKitkat()) {

return;

}

v.post(new Runnable() {

@Override public void run() {

v.setPadding(v.getPaddingLeft(), v.getPaddingTop() + getStatusBarOffsetPx(v.getContext()),

v.getPaddingRight(), v.getPaddingBottom());

v.getLayoutParams().height += getStatusBarOffsetPx(v.getContext());

}

});

}

/**

* 调用私有API处理颜色

*/

private void processPrivateAPI() {

try {

processFlyMe(lightStatusBar);

} catch (Exception e) {

try {

processMIUI(lightStatusBar);

} catch (Exception e2) {

//

}

}

}

private void process() {

//调用私有API处理颜色

processPrivateAPI();

processActionBar(actionBarView);

//处理4.4~5.0沉浸

if (current >= Build.VERSION_CODES.KITKAT && current < Build.VERSION_CODES.M) {

processKitkat();

} else if (current >= Build.VERSION_CODES.M) {

processM();

}

}

/**

* 处理4.4沉浸

*/

@TargetApi(Build.VERSION_CODES.KITKAT) private void processKitkat() {

WindowManager.LayoutParams winParams = window.getAttributes();

final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;

if (transparentStatusBar) {

winParams.flags |= bits;

} else {

winParams.flags &= ~bits;

}

window.setAttributes(winParams);

}

/**

* 改变小米的状态栏字体颜色为黑色, 要求MIUI6以上

* Tested on: MIUIV7 5.0 Redmi-Note3

*/

private void processMIUI(boolean lightStatusBar) throws Exception {

Class extends Window> clazz = window.getClass();

int darkModeFlag;

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);

extraFlagField.invoke(window, lightStatusBar ? darkModeFlag : 0, darkModeFlag);

}

/**

* 改变魅族的状态栏字体为黑色,要求FlyMe4以上

*/

private void processFlyMe(boolean isLightStatusBar) throws Exception {

WindowManager.LayoutParams lp = window.getAttributes();

Class> instance = Class.forName("android.view.WindowManager$LayoutParams");

int value = instance.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON").getInt(lp);

Field field = instance.getDeclaredField("meizuFlags");

field.setAccessible(true);

int origin = field.getInt(lp);

if (isLightStatusBar) {

field.set(lp, origin | value);

} else {

field.set(lp, (~value) & origin);

}

}

@TargetApi(Build.VERSION_CODES.M) private void processM() {

if (current < Build.VERSION_CODES.M) {

return;

}

int flag = window.getDecorView().getSystemUiVisibility();

if (lightStatusBar) {

/**

* 改变字体颜色

* see {@link }

*/

flag |= (WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS

| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

window.setStatusBarColor(Color.TRANSPARENT);

}

if (transparentStatusBar) {

flag |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;

window.setStatusBarColor(Color.TRANSPARENT);

}

if (transparentNavigationbar) {

flag |= (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);

window.setNavigationBarColor(Color.TRANSPARENT);

}

window.getDecorView().setSystemUiVisibility(flag);

}

final public static class Builder {

private Window window;

private boolean lightStatusBar = false;

private boolean transparentStatusbar = false;

private boolean transparentNavigationbar = false;

private View actionBarView;

public Builder setActionbarView(@Nullable View actionbarView) {

this.actionBarView = actionbarView;

return this;

}

private Builder setWindow(@NonNull Window Window) {

this.window = Window;

return this;

}

private Builder setWindow(@NonNull Activity activity) {

this.window = activity.getWindow();

return this;

}

private Builder setWindow(@NonNull Dialog dialog) {

this.window = dialog.getWindow();

return this;

}

public Builder setLightStatusBar(boolean lightStatusBar) {

this.lightStatusBar = lightStatusBar;

return this;

}

public Builder setTransparentStatusbar(boolean transparentStatusbar) {

this.transparentStatusbar = transparentStatusbar;

return this;

}

public Builder setTransparentNavigationbar(boolean transparentNavigationbar) {

this.transparentNavigationbar = transparentNavigationbar;

return this;

}

public void process() {

new StatusBarUtils(window, lightStatusBar, transparentStatusbar, transparentNavigationbar,

actionBarView).process();

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值