Android完全隐藏导航键/虚拟按键和状态栏

之前有做过一个需求,在某一个界面隐藏掉home,主页,返回键这几个虚拟按键以及状态栏,就是要全屏显示,刚开始隐藏了,但是在有用户交互的时候,导航键又显示出来了,纠结了下,最后解决了,现在总结下

1.首先说点其他的,如果你是修改源码,想去掉系统的虚拟按键,在任何界面都不显示的话,可以这样修改:

在system.prop文件里面

# temporary enables NAV bar (soft keys)
qemu.hw.mainkeys=1

qemu.hw.mainkeys这个字段值为0就是显示,值为1就不显示


2.接下来再说下只在某一个界面隐藏导航键和状态栏的方法

    WindowManager mWindowManager = (WindowManager)this.mContext.getSystemService(this.mContext.WINDOW_SERVICE); 
    WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();
    wmParams.format = PixelFormat.RGBA_8888;    
     如果设置为:
     wmParams.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.INVISIBLE | View.SYSTEM_UI_FLAG_FULLSCREEN;
     wmParams.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL|WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
这样可以暂时隐藏,但是当有用户交互点击屏幕的时候,导航键就又显示出来了。

我们来看下源码里面关于 SYSTEM_UI_FLAG_FULLSCREEN和SYSTEM_UI_FLAG_HIDE_NAVIGATION的注释
There is a limitation: because navigation controls are so important, the least user
     * interaction will cause them to reappear immediately.  When this happens, both
     * this flag and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be cleared automatically,
     * so that both elements reappear at the same time.
     *
     * @see #setSystemUiVisibility(int)
     */
    public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002;

就是说android系统有一个限制:因为 navigation的控制是很重要的,用户交互会让它们又重新显示出来,这个时候我们设置的SYSTEM_UI_FLAG_FULLSCREEN 和SYSTEM_UI_FLAG_HIDE_NAVIGATION都会自动被清除掉,所以虚拟键又会重新出现。

解决方法

我们将wmParams.systemUiVisibility这个属性设置成下面这样的

wmParams.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.INVISIBLE | View.SYSTEM_UI_FLAG_FULLSCREEN  | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View .SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
    wmParams.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL|WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;

这样就可以实现了,接下来分析下:

我们来看下源码里面关于SYSTEM_UI_FLAG_IMMERSIVE这个flag的解释

    /**
     * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
     * hiding the navigation bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  If this flag is
     * not set, {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any
     * user interaction.
     * <p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only
     * has an effect when used in combination with that flag.</p>
     */
    public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;

意思就是当setSystemUiVisibility只设置SYSTEM_UI_FLAG_HIDE_NAVIGATION这个属性时,View仍然会保持交互,如果不设置SYSTEM_UI_FLAG_IMMERSIVE这个flag的话,在有任何用户交互的情况下,SYSTEM_UI_FLAG_HIDE_NAVIGATION就会被清除掉。因此只有当SYSTEM_UI_FLAG_HIDE_NAVIGATION和 SYSTEM_UI_FLAG_IMMERSIVE这两个flag一起使用的时候才会有效果。


再来看下源码里面关于SYSTEM_UI_FLAG_IMMERSIVE_STICKY这个flag的解释

 /**
     * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
     * hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the navigation
     * bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  Use this flag to create an immersive
     * experience while also hiding the system bars.  If this flag is not set,
     * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any user
     * interaction, and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be force-cleared by the system
     * if the user swipes from the top of the screen.
     * <p>When system bars are hidden in immersive mode, they can be revealed temporarily with
     * system gestures, such as swiping from the top of the screen.  These transient system bars
     * will overlay app鈥檚 content, may have some degree of transparency, and will automatically
     * hide after a short timeout.
     * </p><p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_FULLSCREEN} and
     * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination
     * with one or both of those flags.</p>
     */
    public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000;

这个跟SYSTEM_UI_FLAG_IMMERSIVE这个属性差不多,解释及自己看,为了设置的flag在有用户交互的时候不被强制清除,因此这个属性要配合SYSTEM_UI_FLAG_FULLSCREEN和SYSTEM_UI_FLAG_HIDE_NAVIGATION一起使用才会有效果。

wmParams.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.INVISIBLE | View.SYSTEM_UI_FLAG_FULLSCREEN|SYSTEM_UI_FLAG_IMMERSIVE_STICKY这个应该就会有效果了,当然为了保险起见,我把所有相关的属性都加上去了。

总结:

当我们设置某个属性或者使用某个api函数达不到预期的效果的时候,我们可以看下源码或者api文档,这样就可以找出问题的原因,从而加以解决。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值