分别用ToolBar和自定义导航栏实现沉浸式状态栏

分别用ToolBar和自定义导航栏实现沉浸式状态栏,第1张

概述一、ToolBar1、在build.gradle中添加依赖,例如:compile\'com.android.support:appcompat-v7:23.4.0\'

一、Toolbar

1、在build.gradle中添加依赖,例如:

compile 'com.androID.support:appcompat-v7:23.4.0'

2、去掉应用的Actionbar。可以是修改主题theme为“NoActionbar”,例如:

<style name="Apptheme" parent="theme.AppCompat.light.NoActionbar">

或者不修改主题为"NoActionbar",而在主题的style下,添加:

 <item name="windowNoTitle">true</item> <item name="windowActionbar">false</item>

第二个属性代表是否用Actionbar代替Titlebar。

其实,刚学的时候,感觉很纳闷,怎么又多了个Titlebar?后来查了很久才发现,3.0以前,状态栏下面的是标题栏(只能显示标题等少量信息),3.0以后就变成了应用栏,也就是Actionbar。

另外,我测试的时候,activity是继承于AppCompatActivity,主题是AppCompat类型的。这种情况下,必须要像上面那样写才有效果,少写或值不同的话,要么没效果,要么报错。

最后,上面两个属性的说明可在androID.R.attr这个类中查看。

3、在xml中为Toolbar添加属性

 androID:fitsSystemwindows="true" androID:minHeight="?attr/actionbarSize"

fitsSystemwindows是Toolbar实现沉浸式状态栏的关键,其大概情况是,如果设为true,就会调整这个vIEw去留一些空间给系统窗口,如果不设置或设为false,Toolbar就会和状态栏重叠在一起。

而第二个属性中,它的值全写是"?androID:attr/actionbarSize",其意思是引用当前主题中的actionbarSize这个属性。更多相关说明可查看官方文档中Accessing Resources的部分。

上面两个属性可在androID.vIEw.VIEw这个类中查看。

4、在java中添加判断sdk版本的代码并在用户的系统是4.4及以上时设置状态栏为透明

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { getwindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}

无论是Toolbar,还是自定义导航栏,这个 *** 作都是实现沉浸式状态栏的关键。

因为设置状态栏为透明的这个属性,要4.4以上才能使用,所以4.4以下的系统是不能够实现沉浸式状态栏的。而在4.4到5.0的系统中,状态栏是全透明的,也就是它的颜色会跟你的Toolbar和自定义导航栏的颜色一样。而在5.0以上的系统中,则是半透明的,也就看起来会比较深暗。

而我在6.0的系统上测试时,发现这一步没设置和设置了的,从效果上看,区别就是没设置时状态栏颜色浅一点,而且Toolbar的padding top为0,而设置了的颜色就深一点,padding top为状态栏的高度。具体有什么影响,还不清楚。但这会让自定义导航的外观变形,它会增加状态栏的高度,但又没有让这部分与状态栏重叠,就导致效果变形。

5、最后在java中添加

setSupportActionbar(mToolbar);

Toolbar的布局代码:

<?xml version="1.0" enCoding="utf-8"?><androID.support.v7.Widget.Toolbar xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:app="http://schemas.androID.com/apk/res-auto" androID:ID="@+ID/tool_bar" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:background="@color/colorPrimary" androID:elevation="4dp" androID:fitsSystemwindows="true" androID:minHeight="?androID:attr/actionbarSize" app:title="Toolbar" app:subtitle="toolbar"/>

 效果图(AndroID 6.0):

二、自定义导航栏topbar

1、设置窗口为无标题,上面第2步中的两个方法都可以实现,或者是在java中添加如下代码:

requestwindowFeature(Window.FEATURE_NO_Title);

注意在添加这句代码时,确保是在加载布局内容之前,也就是onCreate的setContentVIEw之前。在《AndroID群英传》“AndroID控件架构”,这一节中解释了为什么requestwindowFeature()需要在setContentVIEw()之前。

另外,我发现如果该activity是继承AppCompatActivity的话,只写上面的这句代码是没有变化的,显示的还是Actionbar。但如果是继承FragmentActivity的话,就有效果,也就说上面第2步中的第二个方法,只添加其中任意一个属性都是可以的。至于是什么原因,我还没弄清楚。

2、同上面第4步,判断系统版本并按需设置状态栏为透明

3、获取状态栏的高度

protected int getStatusHeight() { try { Class<?> c = Class.forname("com.androID.internal.R$dimen"); // 获得与字符串对应的Class对象 Object object = c.newInstance(); // 创建这个Class的实例对象 FIEld fIEld = c.getFIEld("status_bar_height"); // 拿到字符串对应的变量 int x = Integer.parseInt(fIEld.get(object).toString()); // 通过这个实例对象拿到这个变量的值,再转换类型,最后转为整型,变为一个资源ID return getResources().getDimensionPixelSize(x); } catch (Exception e) { e.printstacktrace(); } return 0;}

这部分代码是利用Java的反射机制来实现的,因为这个internal包默认会被sdk/platforms/android-version中的androID.jar给移除掉,所以无法直接调用或查看这个包中的类。如果要使用的话,可以借助这个开源项目https://github.com/anggrayudi/android-hidden-api。

4、获取自定义topbar的高度并修改布局参数

protected voID setStatusbar() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { final VIEwGroup vIEwGroup = (VIEwGroup) findVIEwByID(R.ID.top_bar); final int statusHeight = getStatusHeight(); vIEwGroup.post(new Runnable() {  @OverrIDe  public voID run() {  int topbarHeight = vIEwGroup.getHeight();  linearLayout.LayoutParams layoutParams = (linearLayout.LayoutParams) vIEwGroup.getLayoutParams();  layoutParams.height = statusHeight + topbarHeight;  vIEwGroup.setLayoutParams(layoutParams);  } }); }}

因为在include这个topbar的布局文件中,其父布局是linearLayout,而topbar的父布局是relativeLayout,所以这里先要转成VIEwGroup,等getLayoutParams时,再转成linearLayout.LayoutParams。

topbar的布局:

<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:ID="@+ID/top_bar" androID:layout_wIDth="match_parent" androID:layout_height="49dp" androID:background="@color/colorPrimary" androID:gravity="bottom"> <relativeLayout androID:layout_wIDth="match_parent" androID:layout_height="49dp"> <TextVIEw  androID:layout_wIDth="wrap_content"  androID:layout_height="wrap_content"  androID:layout_centerInParent="true"  androID:text="@string/app_name"  androID:textSize="24sp"  androID:textcolor="#ffffff"/> </relativeLayout></relativeLayout>

因为这个布局的高度会在代码中动态地修改,即49dp加上状态栏的高度,所以只有一个层级的结构的话,那导航栏的内容就会往上偏。所以要嵌套多一层来维持导航栏的高度,同时在最外层的布局中,添加androID:gravity="bottom"这个属性来保证导航栏不往上偏。

效果图(AndroID 6.0):

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持编程小技巧!

总结

以上是内存溢出为你收集整理的分别用ToolBar和自定义导航栏实现沉浸式状态栏全部内容,希望文章能够帮你解决分别用ToolBar和自定义导航栏实现沉浸式状态栏所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1147240.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存