Android沉溺模式
什么是沉溺模式?
我们理解的沉溺模式都是指状态栏和ActionBar一样的颜色,但其实在设计师那边并不是这个意思,我们这里讨论就按我们曲解的意思讨论吧。
有什么难度
沉溺模式其实一开始是从iOS那边过来的,Android上实现沉溺模式并没有那么简单,Android Kitkat才开始可以在状态栏下面放内容,Lollipop 才支持真正意义上的修改状态连颜色。
但是可悲的是KitKat目前是市场上占有率最高的系统,如果media/不是在Kitkat这个版本上实现并没有什么意义.
实现方式
要想在KitKat上实现改变系统状态栏颜色是不可能的,我们只能通过曲线救国的方式来实现。KitKat上支持一种模式,把内容放到StateBar下面,我们通过这种方式来实现改变状态栏颜色的功能,但是这个方法有几个弊端。第一,原生的Android系统,StateBar是有渐变黑色的,这个无法去掉。第二,开启这个功能后,需要根部的View 启用fitSystemWindow功能,但是启用这个功能之后,根部View的Padding将不能使用。
问题解决方案
为了对开发者透明,也为了不每次都会麻烦,我们对开启fitSystemWindow 这个功能进行了封装,原理就是在原本的根部View上包裹一个FrameLayout ,然后使用FrameLayout开启fitSystemWindow ,这样开发者就可以想操作平常的页面一样去开发新的页面了。
效果预览

代码实现
package com.hangox.aboutsystembartint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import com.readystatesoftware.systembartint.SystemBarTintManager;
/**
* Created With Android Studio
* User hangox
* Date 15/10/20
* Time 下午9:55
* 沉溺状态栏助手
*/
public class SystemBarTintHelper {
private Activity mActivity;
private SystemBarTintManager mTintManager;
public SystemBarTintHelper(Activity activity) {
mActivity = activity;
setUpTranslucentStatus();//开启透明状态栏
mTintManager = new SystemBarTintManager(mActivity);
}
/**
* 开启调用
*/
public void setUp(int color) {
mTintManager.setStatusBarTintEnabled(true);
mTintManager.setStatusBarTintColor(color);
}
/**
* 使用代码启动透明状态栏
*/
@TargetApi(19)
private void setUpTranslucentStatus() {
Window win = mActivity.getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
winParams.flags |= bits;
win.setAttributes(winParams);
}
/**
* 因为如果根部View设置fitSystemWindow = true 后,padding 就会无效,
* 做不到对开发者透明,所以只能在原本的根部View套上一个FrameLayout
* 再对FrameLayout 执行isFitSystem = true这样就不会影响原来的布局
*/
public void handleViewAfterSetContent() {
ViewGroup decorView = (ViewGroup) mActivity.getWindow().getDecorView().findViewById(android.R.id.content);
View rootView = decorView.getChildAt(0);
decorView.removeView(rootView);
View newRootView = generateNewRootView(rootView, null);
newRootView.setFitsSystemWindows(true);
decorView.addView(newRootView);
}
/**
* 生成一个新的根部View
* @param rootView
* @param layoutParams
* @return
*/
public FrameLayout generateNewRootView(View rootView, ViewGroup.LayoutParams layoutParams){
FrameLayout frameLayout = new FrameLayout(mActivity);
if (layoutParams == null) frameLayout.setLayoutParams(rootView.getLayoutParams());
else frameLayout.setLayoutParams(layoutParams);
frameLayout.addView(rootView);
return frameLayout;
}
public static boolean isKitKat() {
return Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT;
}
}
在Activity 的代码
package com.hangox.aboutsystembartint;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
/**
* 示范Activity
*/
public class MainActivity extends AppCompatActivity {
protected SystemBarTintHelper mSystemBarTintHelper ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//透明状态栏只能再kitkat 以上的版本开启,但是Android5.0 之后提供了primaryDark这种东西更改
//状态栏模式,所以只要再kitkat 模式上开启就好了
if (SystemBarTintHelper.isKitKat()) {
mSystemBarTintHelper = new SystemBarTintHelper(this);
// mSystemBarTintHelper.setSystemBarColor(getResources().getColor(R.color.colorPrimaryDark));
mSystemBarTintHelper.setUp(getResources().getColor(R.color.colorPrimaryDark));
}
setContentView(R.layout.activity_main);
}
@Override
public void setContentView(int layoutResID) {
super.setContentView(layoutResID);
if(SystemBarTintHelper.isKitKat()){
mSystemBarTintHelper.handleViewAfterSetContent();
}
}
@Override
public void setContentView(View view) {
if(SystemBarTintHelper.isKitKat()){
view = mSystemBarTintHelper.generateNewRootView(view,null);
}
super.setContentView(view);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
if(SystemBarTintHelper.isKitKat()){
view = mSystemBarTintHelper.generateNewRootView(view, params);
}
super.setContentView(view, params);
}
}