一步两步带你实现android沉浸式设计(代码片段)

花花young 花花young     2022-12-05     297

关键词:

前言

       沉浸式不知道什么时候有了两种叫法,一种是沉浸式模式,一种是沉浸式状态栏,Google从Android4.4开始,给我们开发者提供了一套透明的系统UI样式给状态栏和导航栏,这样完美的玩法简直和IOS系统媲美了。


Part 1、沉浸式模式

    

public void toggle(View view) 
        int options = getWindow().getDecorView().getSystemUiVisibility();
        if (Build.VERSION.SDK_INT >= 14) 
            options ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;//隐藏导航条
        
        if (Build.VERSION.SDK_INT >= 16) 
            options ^= View.SYSTEM_UI_FLAG_FULLSCREEN;//隐藏系统栏
        
        if (Build.VERSION.SDK_INT >= 19) 
            //这里有两种沉浸模式
            //SYSTEM_UI_FLAG_IMMERSIVE_STICKY 你在系统栏区域滑动使得系统栏显示为半透明,
            // 但是你的flag并没有被清除,监听没有被触发,这个系统栏会自动隐藏

            //SYSTEM_UI_FLAG_IMMERSIVE 你在系统栏区域滑动使得系统栏显示,将会保持可见的状态
            options ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        
        getWindow().getDecorView().setSystemUiVisibility(options);
    

如果你想给单个设置,只需要按照下面的参数进行设置即可

getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE  //稳定布局
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //隐藏导航栏
                        | View.SYSTEM_UI_FLAG_FULLSCREEN //隐藏系统栏
                        | View.SYSTEM_UI_FLAG_IMMERSIVE);


Part 2沉浸式状态栏

在Android5.0+自动实现了沉浸式的效果,状态栏的颜色跟随你在主题中的colorPrimaryDark属性,通过样式进行修改

        <item name="android:statusBarColor">@color/system_bottom_nav_color</item>
在代码中进行设置
        getWindow().setStatusBarColor(getResources().getColor(R.color.material_blue_grey_800));
然而对于沉浸式状态栏要做到兼容的效果着实不易,现在最低兼容到4.4以上,可以在style文件进行设置
        <item name="android:windowTranslucentStatus">true</item>
但这种方法并不推荐使用,兼容性不好,在代码中设置
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

似乎设置起来很简单,但是上面的两种会出现严重的bug,状态栏遮挡住了ToolBar

    

面对这样的情况我们快速想到的就是加上android:fitsSystemWindows="true",那么在哪层布局加呢?首先我们先来说一下这个属性的含义:设置布局时,是否考虑当前系统窗口的布局,如果为true就会调整整个系统窗口布局(包括状态栏的view)以适应你的布局,不妨我们尝试一下给ToolBar添加android:fitsSystemWindows="true"

效果~

    

然而ToolBar向上移填充了状态栏部分,这也验证了android:fitsSystemWindows="true"只是让系统窗口布局去适应你设置的控件,针对上面这种效果提供了两种解决方案

1、<推荐>将android:fitsSystemWindows="true"放在最外层的容器,或者你也可以在代码中进行设置

ViewGroup contentView = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);//得到屏幕不包括标题栏的区域
        View rootView = contentView.getChildAt(0);//得到xml的根布局
        if(rootView != null && Build.VERSION.SDK_INT >= 14)
            rootView.setFitsSystemWindows(true);
        

效果~

    

发现给布局最外层容器设置android:fitsSystemWindows="true" 可以达到状态栏透明,并且露出底色---android:windowBackground颜色,这时候需要直接将最外层容器(也可以修改-android:windowBackground颜色)设置成状态栏想要的颜色,下面剩下的布局再包裹一层正常的背景颜色。

效果~

    

这种解决方案不仅可以解决了状态栏遮挡ToolBar的问题,还解决了ScrollView+EditText存在时ToolBar会被顶出去的问题

效果~

    

2、针对状态栏遮挡ToolBar的问题还有另外一种解决方案,就是去掉在ToolBar设置的fitsSystemWindows,增加ToolBar的高度并且为ToolBar设置padding,值得注意是此方案也没有解决ScrollView+EditText会将ToolBar推上去的问题

        //1.先设置toolbar的高度
        ViewGroup.LayoutParams params = mToolbar.getLayoutParams();
        int statusBarHeight = getStatusBarHeight(this);
        params.height += statusBarHeight ;
        mToolbar.setLayoutParams(params );
设置ToolBar的padding

        //2.设置paddingTop,以达到状态栏不遮挡toolbar的内容。
        mToolbar.setPadding(
                mToolbar.getPaddingLeft(),
                mToolbar.getPaddingTop()+getStatusBarHeight(this),
                mToolbar.getPaddingRight(),
                mToolbar.getPaddingBottom());

通过查看android.R.dimen.status_bar_height文件知道需要通过反射来得到状态栏的高度

    public int getStatusBarHeight(Context context) 
        int statusBarHeight = 0;
        try 
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object obj = clazz.newInstance();
            Field field = clazz.getField("status_bar_height");
            int temp = Integer.parseInt(field.get(obj).toString());
            statusBarHeight = context.getResources().getDimensionPixelSize(temp);
         catch (Exception e) 
            e.printStackTrace();
        
        return statusBarHeight;
    
效果~

    


Part 3、沉浸式虚拟导航栏

在Android5.0+实现底部导航沉浸效果,style实现

<item name="android:navigationBarColor">@color/colorPrimary_pink</item>
代码实现
getWindow().setNavigationBarColor()
在Android4.4可以使用特殊手段让导航栏设置为透明颜色,style实现
<item name="android:windowTranslucentNavigation">true</item>

代码实现

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
效果~

    

然而虚拟导航栏遮挡了内容,回头想想可能会想到这种情况和上面状态栏遮挡toolbar是一个问题,上面有两种解决方案但对于虚拟导航栏只能使用增加高度设置padding来解决,但是要如何去解决呢,底部的导航栏却不能像ToolBar一样能获得相应的View。这里我们可以做一个假象,让它下面有个设置为和底部虚拟导航栏高度一样的View并设置背景。开始搞~

1、在布局文件底部定义一个View

    <View
        android:id="@+id/navigationview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@color/colorPrimary"/>
2、在代码中进行动态的设置
        ViewGroup.LayoutParams pras = mNavigationbar.getLayoutParams();
        int navigationBarHeight = getNavigationBarHeight(this);
        pras.height += navigationBarHeight ;
        mNavigationbar.setLayoutParams(pras);
    

    private int getNavigationBarHeight(Context context) 
        int navigationbarBarHeight = 0;
        try 
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object obj = clazz.newInstance();
            Field field = clazz.getField("navigation_bar_height");
            int temp = Integer.parseInt(field.get(obj).toString());
            navigationbarBarHeight = context.getResources().getDimensionPixelSize(temp);
         catch (Exception e) 
            e.printStackTrace();
        
        return navigationbarBarHeight;
    
效果~

    

这样似乎已经解决了导航栏沉浸的效果,但还差点什么,那就是如何判断手机是否有虚拟导航栏或者是否开启了虚拟导航栏,这里说一种常用的思路就是通过判断屏幕的高度-内容的高度>0则存在虚拟导航栏。

	private static boolean hasNavigationBarShow(WindowManager wm)
		Display display = wm.getDefaultDisplay();
		DisplayMetrics outMetrics = new DisplayMetrics();
		//获取整个屏幕的高度
		display.getRealMetrics(outMetrics);
		int heightPixels = outMetrics.heightPixels;
		int widthPixels = outMetrics.widthPixels;
		//获取内容展示部分的高度
		outMetrics = new DisplayMetrics();
		display.getMetrics(outMetrics);
		int heightPixels2 = outMetrics.heightPixels;
		int widthPixels2 = outMetrics.widthPixels;
		int w = widthPixels-widthPixels2;
		int h = heightPixels-heightPixels2;
		return  w>0||h>0;//竖屏和横屏两种情况。
	
至此,我们就可以写出一套兼容性的沉浸式状态栏导航栏了。
if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT
				&&android.os.Build.VERSION.SDK_INT<android.os.Build.VERSION_CODES.LOLLIPOP)
			if(toolbar!=null)
				LayoutParams params = toolbar.getLayoutParams();
				int statusBarHeight = getStatusBarHeight(this);
				params.height += statusBarHeight ;
				toolbar.setLayoutParams(params );
				toolbar.setPadding(
						toolbar.getPaddingLeft(),
						toolbar.getPaddingTop()+getStatusBarHeight(this), 
						toolbar.getPaddingRight(),
						toolbar.getPaddingBottom());
				toolbar.setBackgroundColor(translucentPrimaryColor);
			
			if(bottomNavigationBar!=null)
				if(hasNavigationBarShow(getWindowManager()))
					LayoutParams p = bottomNavigationBar.getLayoutParams();
					p.height += getNavigationBarHeight(this);
					bottomNavigationBar.setLayoutParams(p);
					bottomNavigationBar.setBackgroundColor(translucentPrimaryColor);
				
			
		else if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.LOLLIPOP)
			getWindow().setNavigationBarColor(translucentPrimaryColor);
			getWindow().setStatusBarColor(translucentPrimaryColor);
		else
			//<4.4的,不做处理
		












android一步一步带你实现recyclerview的拖拽和侧滑删除功能

先上效果图: 本篇文章我们来学习一个开源项目Android-ItemTouchHelper-Demo 这个项目使用了RecyclerView的ItemTouchHelper类实现了Item的拖动和删除功能,ItemTouchHelper是v7包下的一个类,我们看一下他的介绍Thisisautilityclasstoaddswip... 查看详情

(第一篇)一步一步带你了解linqtoobject(代码片段)

...函数,我们必须学会委托,这是本文的宗旨。下面开始第一步。在第一步开始之前,我们做点准备工作,建立一个学生类和一个班级类,类结构如下publicclassStudentpublicintIdget;set;publicintCla 查看详情

面试必备透过源码角度一步一步带你分析arraylist扩容机制(代码片段)

一先从ArrayList的构造函数说起ArrayList有三种方式来初始化,构造方法源码如下:/**默认初始容量大小*/privatestaticfinalintDEFAULT_CAPACITY=10;privatestaticfinalObject[]DEFAULTCAPACITY_EMPTY_ELEMENTDATA=;/*默认构造函数,使用初始容量10构造一个空列表... 查看详情

一步一步带你分析requirejs

详细源代码一共就2000多行,来看我这篇分析的同学应该都下载下来了,好了,话不多说,开始: 代码的开头就出现3个全局变量: requirejs,require,definevarrequirejs,require,define;(function(global,setTimeout){balababla......})(this,(typeofsetTime... 查看详情

android如何实现5.0以上图片沉浸式状态栏(代码片段)

Android如何实现5.0以上图片沉浸式状态栏1.设置Theme<stylename="TranslucentTheme"parent="Theme.AppCompat.Light.NoActionBar"> <itemname="android:windowTranslucentNavigation"&g 查看详情

android实现沉浸式全屏(代码片段)

前言本文总结Android实现沉浸式全屏的实现方式。实现沉浸式全屏在一些需要全屏显示的场景下,比如玩游戏、看横屏视频的时候,内容全屏,占满窗口的体验会让用户更加沉浸到对内容的消费中,带来好的用户体验。沉浸式显... 查看详情

(as笔记)android全透明沉浸式主题样式——代码篇(代码片段)

目录1.前言2.Android当前SDK版本号>API19-Android4.43.Android当前SDK版本号>API21-Android5.04.扩展知识点5.完整沉浸式主题代码6.总结1.前言    上一章,介绍了Theme主题设置方式,实现沉浸式主题。那本文就记录代码实现沉浸式... 查看详情

android沉浸式状态栏的实现(代码片段)

...0c;第一个浮现在脑海里的词就是“碎片化”。碎片化是让Android开发者很头疼的问题,相信没有哪位开发者会不喜欢“writeonce,runanywhere”的感觉,碎片化让我们不得不耗费精力去校验代码在各个系统版本、各个机型上是否... 查看详情

android沉浸式(透明)状态栏细研-超级细还附demo(代码片段)

前言在Android4.4中引入了沉浸模式的功能,但这个版本非真正的沉浸模式,应该说是透明模式。Android5.0以后才可以在系统层面实现真正的沉浸式状态栏。沉浸式状态栏是为了与当前使用的App页面风格统一,不会显的那... 查看详情

android实现沉浸式状态栏的效果(代码片段)

...体验。下面我来介绍一下一、标题栏延伸到状态栏适用于Android6.0+因为我的标 查看详情

android沉浸式(透明)状态栏细研-超级细还附demo(代码片段)

前言在Android4.4中引入了沉浸模式的功能,但这个版本非真正的沉浸模式,应该说是透明模式。Android5.0以后才可以在系统层面实现真正的沉浸式状态栏。沉浸式状态栏是为了与当前使用的App页面风格统一,不会显的那... 查看详情

titlelayout——一个android轻松实现通用标准支持沉浸式状态栏的标题栏库(代码片段)

TitleLayout多功能、通用的、可在布局或者使用Java代码实现标题栏;支持沉浸式状态栏,支持左侧返回按钮(不需要手动实现页面返回),左侧支持图片+文字、图片、文字;右侧支持图片、文字等。堆码不易,star支持,万分感谢... 查看详情

android状态栏微技巧,带你真正理解沉浸式模式

最近看到郭神一篇关于"沉浸式状态栏"的文章写得特别好,先码着,以后用到方便查找原文地址http://blog.csdn.net/guolin_blog/article/details/51763825记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我... 查看详情

一步一步带你安装史上最难安装的vim插件——youcompleteme

YouCompleteMeisafast,as-you-type,fuzzy-searchcodecompletionengineforVim.参考: https://github.com/Valloric/YouCompleteMe#full-installation-guide本篇文章默认读者知道什么是unix/linux,vim/vi,YouCompleteMe,如果有不清楚的,S 查看详情

android---沉浸式状态栏(代码片段)

Android—沉浸式状态栏我们的征程是星辰大海,而非人间烟尘文章目录Android---沉浸式状态栏去掉标题栏效果引入依赖沉浸状态栏颜色沉浸状态栏图片去掉标题栏首先去掉对应主题下面的Android自带的ActionBar,只需要在对应... 查看详情

android沉浸式状态栏的实现(代码片段)

...0c;第一个浮现在脑海里的词就是“碎片化”。碎片化是让Android开发者很头疼的问题,相信没有哪位开发者会不喜欢“writeonce,runanywhere”的感觉,碎片化让我们不得不耗费精力去校验代码在各个系统版本、各个机型上是否... 查看详情

android开发笔记沉浸式状态栏(代码片段)

在Android开发中我们越来越重视用户的App操作体验,在使用App中我们主张减少对用户的干扰,经常会提到一致性体验。为了追求界面的风格的一致性,Google官方在Android4.4开始,支持了系统最上方的状态栏(StatusBar)和... 查看详情

沉浸式设计(代码片段)

沉浸式APP设计为了达到状态栏也做变色动画的效果,将状态栏沉浸privatevoidsetStatusBarTranslate()getWindow().requestFeature(Window.FEATURE_NO_TITLE);if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP)Windowwindow=getWindow();window.clearFlags(WindowManager... 查看详情