效果图,因为截屏不显示刘海屏,虚拟机用不习惯,上真机图
注:我的QQ是913811215,这个博客已经帮助多位朋友了,如果耐心细致严格按照这个流程来,是没问题的,如果长时间调试未达到效果,本人支持红包有偿服务,哈哈。
大半年没写博客了(确切说是没转发。。。),安卓开发两年多了,第一年做安卓平板上的launcher,第二年做ReactNative的混合开发,对原生的手机端的APP一直没有独立做过完整的项目,今年下半年跳槽去了家新公司,领导同事都很棒,我一个人负责安卓端的新项目,第一次独立做项目感觉很兴奋,终于有机会将MVP+Dagger2+Retrofit2+Rxjava2这套自己多次学习但是没有机会实践的主流架构用上了。
下面将的沉浸式状态栏,也是第一次做,刚开始试了很多方案,但是没有解决的特别好,发现很多主流的APP在这方面也有各自问题(如状态栏灰色或部分内容跑到状态栏显示异常等),但是也有部分APP解决的特别完美,于是下定决心必须做好。
沉浸式状态栏的实现有两种,一种是在java代码中动态设置透明状态栏,一种是style中设置透明状态栏。如果只是仅仅设置透明的状态栏,会发现布局的顶部内容跑到状态栏上了,在刘海屏会出现部分内容丢失的情况,而且如果是java代码动态适配,还会导致状态栏变灰,我试了很多方法,发现无法解决动态设置导航栏变灰的情况,于是选择设置style的方式。
但是用style设置,如何解决内容跑到状态栏的问题呢?又如何解决刘海屏适配的问题?还有华为等全面屏手机虚拟按键的适配呢?
本文首先解决沉浸式状态栏的问题,手机虚拟按键的适配放在下篇博客。
解决内容跑到状态栏上的问题,其实很简单,只需要设置一个假状态栏就好了,让假状态栏占据原本状态栏的位置,就完美解决了这个问题,顺便解决了刘海屏、美人尖的适配。
如何设置假状态栏?
1.首先讲下大体思路,在activity的布局中最顶部加上一个线性布局(也可以是相对布局或者View),给这个布局设置上你需要的背景色,这个确实麻烦点,不过效果还是不错的。
2.注意事项:
2.1 最好是封装在一个布局文件,通过include引入到各个activity的布局文件,不然万一改颜色 会很麻烦。
2.2 请注意 所有的沉浸式状态栏的layout,根布局都是线性布局
参考工具类代码
//动态的设置隐藏布局的高度
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) titleBar.getLayoutParams(),如果你的layout不是线性布局,请自行修改工具类,不然可能因为布局原因起不到效果。
然后在activity中获取当前这个控件,在onCreate中先获取系统状态栏高度,然后给这个控件设置为状态栏的高度。这样就完成了假状态栏的设置。
titleBar = mRoot.findViewById(R.id.ll_title_bar);
TranslucentStatusUtil.initState(getActivity(), titleBar);
下面是设置的工具类,就两个方法。
public class TranslucentStatusUtil {
/**
* 动态的设置状态栏 实现沉浸式状态栏
*/
public static void initState(Activity activity, LinearLayout titleBar) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明状态栏
// activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//// //透明导航栏
// activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
titleBar.setVisibility(View.VISIBLE);
//获取到状态栏的高度
int statusHeight = getStatusBarHeight(activity);
//动态的设置隐藏布局的高度
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) titleBar.getLayoutParams();
params.height = statusHeight;
titleBar.setLayoutParams(params);
}
}
/**
* 通过反射的方式获取状态栏高度
*
* @return
*/
public static int getStatusBarHeight(Activity activity) {
try {
Class> c = Class.forName("com.android.internal.R$dimen");
Object obj = c.newInstance();
Field field = c.getField("status_bar_height");
int x = Integer.parseInt(field.get(obj).toString());
return activity.getResources().getDimensionPixelSize(x);
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
然后,我们再设置style,设置为透明状态栏
v-21
v-19
要加在不同的文件夹,适配不同版本的系统。
BaseActivity中 onCreate()中
setContentView(getContentView());
//沉浸式状态栏适配
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
然后,清单文件中给activity设置相应的主题
大功告成,就是这么简单,而且非常好用,不信就试试吧,照片丑了点,实际效果主流大厂APP一样(比部分适配的强),下面是我的虚拟按键适配,不要错过,下面中实际使用,并且随系统中设置虚拟按键样式以及隐藏显示变化,完美适配。https://blog.csdn.net/qq_34161388/article/details/84259435