华为手机导航栏底部导航栏不能用

Android之framework修改底部导航栏NavigationBar动态显示和隐藏
大家都知道,从3.0版本开始就加入了NavigationBar,主要是为那些没有实体按键的设备提供虚拟按键,但是,它始终固定在底部,占用48dp的像素高度,尽管从android 4.4开始可以全透明,使用这一部分像素,但三个按钮始终悬浮在屏幕上,这对于有强迫症的朋友来说是无法忍受的。因此,本文的目的就是修改framework部分代码,可以动态隐藏和显示NavigationBar,同时又尽量不影响的正常。
主要思路:
在NavigationBar的布局左部加入一个Button(在SystemUI模块实现),点击隐藏NavigationBar,即将NavigationBar从WindowManager中移除掉。需要的时候,通过一个从屏幕底部向上的滑动手势(在policy模块实现)调出NavigationBar。如下两图对比所示:一张为移除前,另一张为移除后。
具体实现:
①.增加按钮实现动态隐藏,主要修改在frameworks/base/packages/SystemUI模块,首先我们增加一个按钮,主要修改
frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml文件,图片资源和字符串我就不提了,具体如下:
diff --git a/frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml b/frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml
index 6aafc 100644
--- a/frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml
@@ -42,12 +42,28 @@
&framelayout android:layout_height="match_parent" android:layout_weight="0" android:layout_width="@dimen/navigation_extra_key_width"&
&/framelayout&
&framelayout android:layout_height="40dp" android:layout_weight="0" android:layout_width="match_parent"&
&/framelayout&
接下来修改frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java,为按钮提供一个接口,具体如下:
diff --git a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 88e71e2..644
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -45,6 +45,7 @@ import com.android.systemui.R;
import com.android.systemui.statusbar.BaseStatusB
import com.android.systemui.statusbar.DelegateViewH
import com.android.systemui.statusbar.policy.DeadZ
+import com.android.systemui.statusbar.policy.KeyButtonR
import com.android.systemui.statusbar.policy.KeyButtonV
import java.io.FileD
@@ -265,6 +266,13 @@ public class NavigationBarView extends LinearLayout {
public View getImeSwitchButton() {
return mCurrentView.findViewById(R.id.ime_switcher);
//BEGIN liweiping
public View getHideBarButton() {
View view = mCurrentView.findViewById(R.id.hide_bar_btn);
view.setBackground(new KeyButtonRipple(getContext(), view));
//END liweiping
private void getIcons(Resources res) {
mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back);
@@ -412,7 +420,6 @@ public class NavigationBarView extends LinearLayout {
mCurrentView = mRotatedViews[Surface.ROTATION_0];
getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
updateRTLOrder();
最后便是在frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java实现点击事件了:
private final OnClickListener mHideBarClickListener = new OnClickListener() {
public void onClick(View view) {
Log.i(way, mHideBarClickListener
onClick...);
removeNavigationBar();
private void removeNavigationBar() {
if (DEBUG) Log.d(TAG, removeNavigationBar: about to remove
+ mNavigationBarView);
if (mNavigationBarView == null)
mWindowManager.removeView(mNavigationBarView);
mNavigationBarView =
到此,隐藏NavigationBar告一段落了。
②.接下来便是显示NavigationBar,这个修改相对复杂一点。因为此时NavigationBar处于不可见状态,我们无法通过增加按钮的方式让其显示,但是我们知道,状态栏下拉通过手势向下滑动即可。因此很容易便想到通过手势从屏幕底部向上滑动来显示NavigationBar。我的想法是在policy模块中增加一个接口,通过frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java服务传递到状态栏中,从而触发显示NavigationBar事件。
也许大家会有疑问,为什么是在policy模块修改?其实我这只是一种解决方案,因为我知道
frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java 有现成的手势滑动接口。其实你也可以SystemUI中增加一个这样的事件,我们需要的就是这么一个触发事件。
PhoneWindowManager.java的修改主要是实现onSwipeFromBottom(竖屏时)和onSwipeFromRight(横屏时)两个接口,然后调用showNavigationBar,在showNavigationBar函数中,我们调用StatusBarManagerService服务中的showNavigationBar函数,具体如下:
diff --git a/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index bb53e12..0644
--- a/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -41,27 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void onSwipeFromBottom() {
if (mNavigationBar != null && mNavigationBarOnBottom) {
requestTransientBars(mNavigationBar);
Log.i(way, onSwipeFromBottom... mNavigationBar != null && mNavigationBarOnBottom);
//BEGIN liweiping
Log.i(way, onSwipeFromBottom...);
showNavigationBar();
//END liweiping
public void onSwipeFromRight() {
if (mNavigationBar != null && !mNavigationBarOnBottom) {
requestTransientBars(mNavigationBar);
Log.i(way, onSwipeFromRight... mNavigationBar != null && !mNavigationBarOnBottom);
//BEGIN liweiping
Log.i(way, onSwipeFromRight...);
showNavigationBar();
//END liweiping
public void onDebug() {
@@ -07,24 @@ public class PhoneWindowManager implements WindowManagerPolicy {
goingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
//BEGIN liweiping
private void showNavigationBar(){
mHandler.post(new Runnable() {
public void run() {
IStatusBarService statusbar = getStatusBarService();
if (statusbar != null) {
statusbar.showNavigationBar();
} catch (RemoteException e) {
// re-acquire status bar service next time it is needed.
mStatusBarService =
//END liweiping
private void updateKeyAssignments() {
final boolean hasMenu = (mDeviceHardwareKeys & KEY_MASK_MENU) != 0;
final boolean hasHome = (mDeviceHardwareKeys & KEY_MASK_HOME) != 0;
这时事件传递到了StatusBarManagerService中,我们来看看StatusBarManagerService.java如何实现showNavigationBar:
diff --git a/frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index f85e2d9..3f
--- a/frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -366,6 +366,27 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
WindowManager.LayoutParams);
//BEGIN liweiping
public void showNavigationBar() {
enforceStatusBar();
android.util.Log.d(way, TAG +
showNavigationBar...);
synchronized(mLock) {
mHandler.post(new Runnable() {
public void run() {
if (mBar != null) {
mBar.showNavigationBar();
} catch (RemoteException ex) {
//END liweiping
private void updateUiVisibilityLocked(final int vis, final int mask) {
if (mSystemUiVisibility != vis) {
从上述代码可以看出,StatusBarManagerService只是起到一个传递作用,将消息传递到StatusBar中,最终的实现是在SystemUI模块的frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java,如下所示:
diff --git a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 9db875f..4f24b6e 100644
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -56,6 +56,7 @@ public class CommandQueue extends IStatusBar.Stub {
private static final int MSG_BUZZ_BEEP_BLINKED
= 15 && MSG_SHIFT;
private static final int MSG_NOTIFICATION_LIGHT_OFF
= 16 && MSG_SHIFT;
private static final int MSG_NOTIFICATION_LIGHT_PULSE
= 17 && MSG_SHIFT;
private static final int MSG_SHOW_NAVIGATIONBAR
= 18 && MSG_SHIFT;//ADD liweiping
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 && 0;
@@ -83,6 +84,7 @@ public class CommandQueue extends IStatusBar.Stub {
public void animateCollapsePanels(int flags);
public void animateExpandSettingsPanel();
public void setSystemUiVisibility(int vis, int mask);
public void showNavigationBar();//ADD liweiping
public void topAppWindowChanged(boolean visible);
public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
boolean showImeSwitcher);
@@ -154,6 +156,14 @@ public class CommandQueue extends IStatusBar.Stub {
mHandler.obtainMessage(MSG_SET_SYSTEMUI_VISIBILITY, vis, mask, null).sendToTarget();
//BEGIN liweiping
public void showNavigationBar() {
synchronized (mList) {
mHandler.removeMessages(MSG_SHOW_NAVIGATIONBAR);
mHandler.sendEmptyMessage(MSG_SHOW_NAVIGATIONBAR);
//END liweiping
public void topAppWindowChanged(boolean menuVisible) {
synchronized (mList) {
@@ -283,6 +293,11 @@ public class CommandQueue extends IStatusBar.Stub {
case MSG_SET_SYSTEMUI_VISIBILITY:
mCallbacks.setSystemUiVisibility(msg.arg1, msg.arg2);
//BEGIN liweiping
case MSG_SHOW_NAVIGATIONBAR:
mCallbacks.showNavigationBar();
//END liweiping
case MSG_TOP_APP_WINDOW_CHANGED:
mCallbacks.topAppWindowChanged(msg.arg1 != 0);
CommandQueue.java收到了这个消息之后,又回调给了base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java,绕了大半天,消息终于回来了,我们就是需要在PhoneStatusBar.java实现显示NavigationBar的函数了:
@Override // CommandQueue
public void showNavigationBar() {
Log.i(way, TAG +
showNavigationBar...);
forceAddNavigationBar();
private void forceAddNavigationBar() {
// If we have no Navbar view and we should have one, create it
if (mNavigationBarView != null) {
mNavigationBarView =
(NavigationBarView) View.inflate(mContext, R.layout.navigation_bar, null);
mNavigationBarView.setDisabledFlags(mDisabled);
mNavigationBarView.setBar(this);
addNavigationBar(true); // dynamically adding nav bar, reset System UI visibility!
private void prepareNavigationBarView(boolean forceReset) {
mNavigationBarView.reorient();
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
mNavigationBarView.getRecentsButton().setLongClickable(true);
mNavigationBarView.getRecentsButton().setOnLongClickListener(mLongPressBackRecentsListener);
mNavigationBarView.getBackButton().setLongClickable(true);
mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener);
mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
mNavigationBarView.getHideBarButton().setOnClickListener(mHideBarClickListener);//ADD liweiping
if (forceReset) {
// Nav Bar was added dynamically - we need to reset the mSystemUiVisibility and call
// setSystemUiVisibility so that mNavigationBarMode is set to the correct value
Log.i(way, prepareNavigationBarView mNavigationBarMode = + mNavigationBarMode +
mSystemUiVisibility =
+ mSystemUiVisibility +
mNavigationIconHints =
+ mNavigationIconHints);
mNavigationBarMode = 0;
int newVal = mSystemUiV
mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
setSystemUiVisibility(newVal, /*SYSTEM_UI_VISIBILITY_MASK*/0xffffffff);
int hints = mNavigationIconH
mNavigationIconHints = 0;
setNavigationIconHints(hints);
topAppWindowChanged(mShowMenu);
updateSearchPanel();
// For small-screen devices (read: phones) that lack hardware navigation buttons
private void addNavigationBar(boolean forceReset) {
if (DEBUG) Log.v(TAG, addNavigationBar: about to add
+ mNavigationBarView);
if (mNavigationBarView == null)
prepareNavigationBarView(forceReset);
mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
//END liweiping
需要注意的是:
①显示NavigationBar时,需要重新实例化一次NavigationBarView,我之前有试过移除NavigationBarView后未置空,下次添加时直接使用,会出现状态栏重启的情况,具体原因未知,log显示动画播放错误之类。
②重新添加NavigationBarView时需要恢复NavigationBarView之前的状态,比如说隐藏前时是透明的、显示输入法按钮、菜单键等等。
③本文是在Android5.0的代码上修改的,其他版本未验证。
④本文仅是提供一种思路,并非最优方案。华为手机导航栏没反应是怎么回事?_百度宝宝知道
&&>&&帖子详情
&发帖:5644077
&用户:6640091
华为手机导航栏没反应是怎么回事?
血红色的棺木
宝宝6岁以上LV.1
华为手机导航栏没反应是怎么回事?
果儿718718
宝宝10个月LV.20
去修理的地方问问
扫码或保存
邀请好友扫一扫分享给TA或者华为手机这样设置,导航栏瞬间变得高大上
华为手机这样设置,导航栏瞬间变得高大上
华为手机底部的导航栏,默认情况下是三个图标,而且导航栏是固定不能隐藏的。
其实,通过设置,可以把导航栏变成下图的式样,左边多了一个【下沉】按钮,可以把导航栏隐藏起来,向上拉又可以把导航栏显示出来;右边多了一个【通知栏下拉】图标,按一下这个图标,代替了顶部的通知栏下拉,方便很多了。
下面,快跟我来设置一下吧:
1、点击【设置】——【智能辅助】
2、把【导航栏可隐藏】开关打开,把你喜欢的样式选中:
OK,现在你再看看,你的导航栏是立即高大上了?华为Mate7导航栏怎么隐藏 华为Mate7导航栏隐藏方法
时间: 16:35:58来源:作者:不详(0)
为了看上去更加的美观不少华为华为Mate7手机用户都习惯将导航栏隐藏,可能有些新用户还不知道怎么用,下面就为大家带来华为Mate7导航栏隐藏方法。华为Mate7导航栏隐藏方法打开系统设置下拉找到“导航栏选项”然后选择“导航栏应藏”关闭即可。  了解后才知道,华为手机导航栏真方便强大,但为什么没有看见宣传呢?很多人都不知道。
  1、正如有人说的一样,相对于华为其他那些伟大的成就都还没有宣传过来,导航栏可调确实比较小的一件事。比如华为的双摄像头技术、自己研发的顶级手机芯片、自研的基带芯片ISP图像处理芯片、省电技术以及在操作系统方面的革命性18个月流畅改变、硬件和外观进步都是小的一方面。
  2、但其实,老砖家觉得,平心而论,华为导航栏非常牛逼,可调功能多确实挺灵活,挺方便。
  1)导航键在任何时候可以隐藏,如看视频,玩游戏的时候,如下图设置界面,当然,你可以选择不隐藏。设置后的效果如下图的最下面导航栏左边向下箭头:
  2)导航按键返回键和多任务键左右可以调节在左边还是右边,适应任何习惯的人。
  3)还可以设置下拉顶部消息栏按键,如上图导航栏的最有边向下两横加一个箭头。
  4)下面的图就是隐藏的效果,你可以看到截图下面没有导航栏。需要操作时从手机底部向上滑动就出来了。
  5)华为导航栏还有很多功能,如长按住主页键会调出语音助手,下图以刚刚发布的荣耀V9手机为例子说明:
  6)左右滑动导航栏,则整个手机屏幕可以朝滑动的一边变小,再反方向滑动,则会恢复,这对于大屏手机单手操作非常方便。如下荣耀V9手机的两张照片所示,可以看到手机桌面已经调小到了左边或者右边了,这样单手拨打电话发信息就方便了。
  2、有的不了解的人或者别有用心的人说华为导航虚拟键没有实体键好,这个老砖家要发表下看法。对于华为来说,其实这不是技术问题。
  3、对于5.5英寸大屏手机来说,虚拟键比物理实体键操作要方便。因为虚拟键比实体键位置高,你单手操作时拇指滑动的距离短,不要那么去扭曲拇指,对拇指的伤害小。
  4、实体键比虚拟键容易坏,因为是硬件的东西。
  5、虚拟键比实体键要灵敏。
  6、荣耀2.21刚发布的荣耀V9手机(孙杨代言)和荣耀8青春版(吴亦凡代言)也是虚拟键,老砖家就很喜欢:
声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。}

我要回帖

更多关于 华为手机导航栏失灵 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信