安卓沉浸式状态栏以及适配刘海屏

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34161388/article/details/84258457

效果图,因为截屏不显示刘海屏,虚拟机用不习惯,上真机图

大半年没写博客了(确切说是没转发。。。),安卓开发两年多了,第一年做安卓平板上的launcher,第二年做ReactNative的混合开发,对原生的手机端的APP一直没有独立做过完整的项目,今年下半年跳槽去了家新公司,领导同事都很棒,我一个人负责安卓端的新项目,第一次独立做项目感觉很兴奋,终于有机会将MVP+Dagger2+Retrofit2+Rxjava2这套自己多次学习但是没有机会实践的主流架构用上了。

   下面将的沉浸式状态栏,也是第一次做,刚开始试了很多方案,但是没有解决的特别好,发现很多主流的APP在这方面也有各自问题(如状态栏灰色或部分内容跑到状态栏显示异常等),但是也有部分APP解决的特别完美,于是下定决心必须做好。

    沉浸式状态栏的实现有两种,一种是在java代码中动态设置透明状态栏,一种是style中设置透明状态栏。如果只是仅仅设置透明的状态栏,会发现布局的顶部内容跑到状态栏上了,在刘海屏会出现部分内容丢失的情况,而且如果是java代码动态适配,还会导致状态栏变灰,我试了很多方法,发现无法解决动态设置导航栏变灰的情况,于是选择设置style的方式。

但是用style设置,如何解决内容跑到状态栏的问题呢?又如何解决刘海屏适配的问题?还有华为等全面屏手机虚拟按键的适配呢?

  本文首先解决沉浸式状态栏的问题,手机虚拟按键的适配放在下篇博客。

解决内容跑到状态栏上的问题,其实很简单,只需要设置一个假状态栏就好了,让假状态栏占据原本状态栏的位置,就完美解决了这个问题,顺便解决了刘海屏、美人尖的适配。

如何设置假状态栏?

  1.首先讲下大体思路,在activity的布局中最顶部加上一个线性布局(也可以是相对布局或者View),给这个布局设置上你需要的背景色,这个确实麻烦点,不过效果还是不错的。

 2.注意事项:

   2.1 最好是封装在一个布局文件,通过include引入到各个activity的布局文件,不然万一改颜色 会很麻烦。

   2.2 请注意动态设置状态栏高度的代码,是线性布局嵌套线性布局,要根据自己的布局修改,别忘了改代码,不然可能因为布局原因起不到效果。

<LinearLayout
    android:id="@+id/ll_title_bar"
    android:layout_width="fill_parent"
    android:layout_height="1dp"
    android:orientation="vertical"
    android:visibility="gone" />

然后在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,设置为透明状态栏

<style name="TranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentStatus">false</item>
    <item name="android:windowTranslucentNavigation">false</item>
    <!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>
v-21
<style name="TranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentStatus">false</item>
    <item name="android:windowTranslucentNavigation">false</item>
    <item name="android:statusBarColor" tools:ignore="NewApi">@android:color/transparent</item>
</style>

v-19
<style name="TranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
</style>

要加在不同的文件夹,适配不同版本的系统。

BaseActivity中 

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

猜你喜欢

转载自blog.csdn.net/qq_34161388/article/details/84258457