永发信息网

如何控制android系统中NavigationBar 的显示与隐藏

答案:2  悬赏:70  手机版
解决时间 2021-04-09 01:41
如何控制android系统中NavigationBar 的显示与隐藏
最佳答案
设置config_showNavigationBar为true显示,false隐藏。

android4.0以后添加了虚拟导航栏(NavigationBar)新特性,就是在手机和平板的屏幕下面添加了(Back返回键,Home键等),但是手机上都有硬性按键,所以我们有时间要去掉或者隐藏掉虚拟按键。
这些按键其实是button,是android原生自带的,我们可以通过config控制其开和关。对应的config项是:"config_showNavigationBar".

解决方法一:<bool name="config_showNavigationBar">true</bool>
不同的软件版本,配置文件修改不同,下面以android4.2版本为例。在源码frameworks层有两个config.xml文件:
alps\frameworks\base\core\res\res\values\config.xml(1) 和alps\mediatek\custom\project_name\resource_overlay\generic\frameworks\base\core\res\res\values\config.xml
(2)
如果您的源码下只有文件(1), 那就修改config.xml中的<bool name="config_showNavigationBar">true</bool>如果您的源码下只有文件
(1)和(2), 那就修改(2) 中config.xml的<bool name="config_showNavigationBar">true</bool>就行了。隐藏就设成false。

解决方法二:修改framework层NavigationBar显示boolean使其不在屏幕显示。修改类位置:frameworks/base/policy/src/com/android/internal/policy/impl的PhoneWindowManager.java
修改方法:public boolean hasNavigationBar(){
return mHasNavigationBar;
}把hasNavigationBar()方法的返回值改成false就行了。
解决方法二修改过后,手机主屏幕下方会有一个黑色条条,建议使用方法一。
全部回答
我们使用的大多数android手机上的Home键,返回键以及menu键都是实体触摸感应按键。如果你用Google的Nexus4或Nexus5话,你会发现它们并没有实体按键或触摸感应按键,取而代之的是在屏幕的下方加了一个小黑条,在这个黑条上有3个按钮控件,这种设置无疑使得手机的外观的设计更加简约。但我遇到身边用Nexus 4手机的人都吐槽这种设计,原因很简单:好端端的屏幕,被划出一块区域用来显示3个按钮(如下图所示):Back, Home, Recent。并且它一直用在那里占用着。 在android源码中,那一块区域被叫做NavigationBar。同时,google在代码中也预留了标志,用来控制它的显示与隐藏。NavigationBar的显示与隐藏的控制是放在SystemU中的,具体的路径是:\frameworks\base\packages\SystemUI。对android4.0以上的手机而言,SystemUi包含两部分:StatusBar和NavigationBar。在SystemUI的工程下有一个类PhoneStatusBar.java,在该类中可以发现关于控制NavigationBar的相关代码: 在start()方法里可以看到NavigationBar是在那时候被添加进来,但只是添加,决定它显示还是隐藏是在后面控制的。 <span style="font-size:18px;">@Override public void start() { mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay(); updateDisplaySize(); /// M: Support Smartbook Feature. if (SIMHelper.isMediatekSmartBookSupport()) { /// M: [ALPS01097705] Query the plug-in state as soon as possible. mIsDisplayDevice = SIMHelper.isSmartBookPluggedIn(mContext); Log.v(TAG, "start, mIsDisplayDevice=" + mIsDisplayDevice); } super.start(); // calls createAndAddWindows() addNavigationBar(); // Lastly, call to the icon policy to install/update all the icons. mIconPolicy = new PhoneStatusBarPolicy(mContext); mHeadsUpObserver.onChange(true); // set up if (ENABLE_HEADS_UP) { mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(SETTING_HEADS_UP), true, mHeadsUpObserver); } }</span> 其中的addNavigationBar()具体的实现方法如下: <span style="font-size:18px;"> // For small-screen devices (read: phones) that lack hardware navigation buttons private void addNavigationBar() { if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView); if (mNavigationBarView == null) return; prepareNavigationBarView(); mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams()); }</span> 可以看到Navigationbar实际上windowmanager向window窗口里添加一个view。在调用addNavigationBar()方法之前会回调start()的父方法super.start()来判断是否要添加NavigationBar。在super.start()的调用父类方法里会调用createAndAddWindows(),该方法内会判断是否需要添加显示NavigationBar,然后决定是否要实例化NavigationBarView. <span style="font-size:18px;">try { boolean showNav = mWindowManagerService.hasNavigationBar(); if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav); if (showNav) { mNavigationBarView = (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null); mNavigationBarView.setDisabledFlags(mDisabled); mNavigationBarView.setBar(this); } } catch (RemoteException ex) { // no window manager? good luck with that }</span> WindowManagerService类实现了WindowManagerPolicy的接口,所以WindowManagerService会回调WindowManagerPolicy 的hasNavigationBar()接口, <span style="font-size:18px;"> @Override public boolean hasNavigationBar() { return mPolicy.hasNavigationBar(); }</span> Policy向下调用实际上调用的是PhoneWindowManager实现的hasNavigationBar方法,下面代码是PhoneWindowManager中的hasNavigationBar()方法。 <span style="font-size:18px;">// Use this instead of checking config_showNavigationBar so that it can be consistently // overridden by qemu.hw.mainkeys in the emulator. public boolean hasNavigationBar() { return mHasNavigationBar; }</span> 而mHasNavigationBar的赋值可以在PhoneWindowManager中的setInitialDisplaySize(Display display, int width, int height, int density)方法中找到, <span style="font-size:18px;"> if (!mHasSystemNavBar) { mHasNavigationBar = mContext.getResources().getBoolean( com.android.internal.R.bool.config_showNavigationBar); // Allow a system property to override this. Used by the emulator. // See also hasNavigationBar(). String navBarOverride = SystemProperties.get("qemu.hw.mainkeys"); if (! "".equals(navBarOverride)) { if (navBarOverride.equals("1")) mHasNavigationBar = false; else if (navBarOverride.equals("0")) mHasNavigationBar = true; } } else { mHasNavigationBar = false; }</span> 从上面代码可以看到mHasNavigationBar的值的设定是由两处决定的: 1.首先从系统的资源文件中取设定值config_showNavigationBar, 这个值的设定的文件路径是frameworks/base/core/res/res/values/config.xml <!-- Whether a software navigation bar should be shown. NOTE: in the future this may be autodetected from the Configuration. --> <bool name="config_showNavigationBar">false</bool> 2.然后系统要获取“qemu.hw.mainkeys”的值,这个值可能会覆盖上面获取到的mHasNavigationBar的值。如果 “qemu.hw.mainkeys”获取的值不为空的话,不管值是true还是false,都要依据后面的情况来设定。 所以上面的两处设定共同决定了NavigationBar的显示与隐藏。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
爱情公寓到底会不会有第五季
单选题中华民族的传统节日春节即将到来,小明
求地震中的那句话,一个困难除以十三亿
参加培训情况怎么填写,培训形式 办学形式是什
害怕找工作,不敢问人家要不要人,正常吗
力帆620 缸压7个够不够
爱情讽刺人的经典语句,讽刺有钱人的经典语句
某化合物化学式为HnRO2n-1,若n=2时,R的化合
宁波市江东捷达汽修厂这个地址在什么地方,我
六年级数学上册分数乘除法应用题类型,如(谁
宝贝,蔡佩婷 韩语怎样写
倾城之恋观后感
女的带有“珠”,男的带有“勋”的情侣网名
安徽机场有几个,请教有谁坐过老挝航空公司的
监护人能否干涉被监护人的隐私权
推荐资讯
今天2016年6月12日上海市外地车牌可以上高架
怎么测试妈妈爱不爱我
单选题Alltheguestsdislikedthesaltedf
吴姓取名字哪个好听啊?
拍X光看到黑色部分
写母爱的诗句现代诗,关于母爱的现代诗
《昆仑》《沧海》中,金刚门的32身相是哪32身
驾驶船的人叫什么
单选题1+3+5+7+…+99的和是A.2500B.5050C.252
要评职称,报到证不知道在哪?
cs(反恐精英)是用什么程序语言写的啊?用什么
一个QQ号在英雄联盟上创建了好几个区,为什么
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?