配色
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/darkGray</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
布局
activity_main.xml
<RelativeLayout
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.support.v7.widget.Toolbar
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"/>
</RelativeLayout>
代码
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
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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">
<include layout="@layout/toolabr"/>
<TextView
android:fitsSystemWindows="true"
android:clipToPadding="false"
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
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
<RelativeLayout
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.support.v7.widget.Toolbar
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"/>
</RelativeLayout>
处理4.4以上的沉浸
处理6.0以上的沉浸与字体颜色,5.0只可以处理沉浸而不能改字体颜色(故不建议用白色背景)
调用私有API处理小米魅族的状态栏字体颜色
获取状态栏高度
状态栏背景取决于你的Toolbar
另外提供Toolbar的高度自动适配作为参考
截图
方法一:状态栏的使用
在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 <a href="https://developer.android.com/reference/android/R.attr.html#windowLightStatusBar"></a>}
*/
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();
}
}
}