最近在接手一个项目,需要在旧的代码基础上添加沉浸式通知栏。因此这段时间专门研究了一下网上已有的例子,发现不太适用当前项目,主要原因是当前项目不同的页面顶部标题栏的颜色不一样,特别是个人中心页面可以切换皮肤,而网上的例子大 部分没考虑到这种情况。经过多方面考虑,决定自己动手写。
所谓的沉浸式通知栏就是把用来导航的各种界面操作空间隐藏在以程序内容为主的情景中,通过相对“隐形”的界面来达到把用户可视范围最大化地用到内容本身上。而最新安卓4.4系统的通知栏沉浸模式就是在软件打开的时候通知栏和软件顶部颜色融为一体,这样不仅可以使软件和系统本身更加融为一体。(如下图所示)
具体实现方式如下:
1.新建个公共style,设置android:fitsSystemWindows=true
<!-- 设置应用布局时是否考虑系统窗口布局;true -->
<style name="AppBaseTheme" parent="android:Theme.Light.NoTitleBar">
<item name="android:fitsSystemWindows">true</item>
</style>
2. 修改AndroidManifest.xml,让所有的activity样式默认设置为AppBaseTheme(*不同项目要灵活处理,笔者项目的activity样式都是统一的所以这样设置没问题,但是实际情况下不同的activity可能调用的样式不一样,需要读者自行按自己的项目来设置)
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppBaseTheme"
android:name="****">
3.新增沉浸式通知栏实现类,实现原理很简单。
1)判断当前系统版本是不是4.4以上,判断代码如下:
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT)
2)如果大于4.4则设置状态栏透明化,代码如下:
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
3)获取activity的根rootView(DecorView),然后创建一个新的view stateBarView并把它添加到rootView(这里手动给它设置个ID,下次进来时先判断rootView是否已创建stateBarView,如果已创建则直接获取该View这样可以防止重复创建,导致内存泄露)
以下是具体代码实现
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout.LayoutParams;
/**
* 沉浸式通知栏公共类
* @author hurrican
*
*/
@SuppressLint({ "InlinedApi", "ResourceAsColor" })
public class ImmersedNotificationBar {
private Activity activity ;
//设置沉浸式通知栏的ID(防止重复创建)
private final static int IMMERSED_NOTIFICATION_BAR_ID = 12345678 ;
private final static String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height" ;
public ImmersedNotificationBar(Activity activity){
this.activity = activity ;
}
//获取状态栏高度
private int getStatusBarHeight(Resources res){
int statusBarHeight = 0;
int resourceId = res.getIdentifier(STATUS_BAR_HEIGHT_RES_NAME, "dimen", "android");
if (resourceId > 0) {
statusBarHeight = res.getDimensionPixelSize(resourceId);
}
return statusBarHeight ;
}
//添加顶部状态栏
private View addStateBar(Activity activity,ViewGroup rootView,int statusBarHeight){
//创建新的View,并添加到rootView顶部)
View statusBarView ;
if(null!=rootView.findViewById(IMMERSED_NOTIFICATION_BAR_ID)){
statusBarView = rootView.findViewById(IMMERSED_NOTIFICATION_BAR_ID);
}else{
statusBarView = new View(activity);
rootView.addView(statusBarView);
}
statusBarView.setId(IMMERSED_NOTIFICATION_BAR_ID) ;
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,statusBarHeight);
params.gravity = Gravity.TOP;
statusBarView.setLayoutParams(params);
statusBarView.setVisibility(View.VISIBLE);
return statusBarView ;
}
/**
* 设置状态栏颜色
* @param ColorId
*/
public void setStateBarColor(int ColorId){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = activity.getWindow();
//activity的顶级布局
ViewGroup rootView = (ViewGroup) window.getDecorView();
//透明化状态栏
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
Resources res = activity.getResources();
//获取状态栏目的高度
int statusBarHeight = getStatusBarHeight(res);
View stateBarView = addStateBar(activity,rootView,statusBarHeight) ;
stateBarView.setBackgroundColor(ColorId) ;
}
}
/**
* 设置状态栏颜色
* @param ColorId
*/
public void setStateBarDrawable(Drawable drawable){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = activity.getWindow();
//activity的顶级布局
ViewGroup rootView = (ViewGroup) window.getDecorView();
//透明化状态栏
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
Resources res = activity.getResources();
//获取状态栏目的高度
int statusBarHeight = getStatusBarHeight(res);
View stateBarView = addStateBar(activity,rootView,statusBarHeight) ;
stateBarView.setBackgroundDrawable(drawable) ;
}
}
}
使用方法很简单,在onCreate方法里面创建一个ImmersedNotificationBar对象,然后调用setStateBarColor或setStateBarDrawable方法,因为本人的项目每个页面顶部颜色不一致,所以本人是在onResume方法中设置状态栏颜色,以下是本人项目中的代码,仅供参考
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.context = this ;
initView();
notificationBar = new ImmersedNotificationBar(this) ;
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
notificationBar.setStateBarColor(this.getResources().getColor(R.color.red)) ;
}
*文笔不好,有看不明白的可以留言也可以发送问题到我邮箱,共同探讨,共同进步。本人的邮箱地址是: hurrican_ok@126.com 正常情况下本人一周至少会登陆一次。如果不能及时回复请见谅