我们都知道Android系统的导航栏通常有三个按键,分别是BACK, HOME, APP_SWITCH. 网上很多有关导航栏和状态栏显隐的文章,但几乎都是控制导航栏或状态栏所有按键同时显示或消失,如果我们想定制一种接口,它可以控制我们的导航栏三个按键中的某一个按键的显示或隐藏,我们该怎么做呢?
其实很简单,导航栏作为系统应用SystemUI的一部分,导航栏的那三个按键也有对应的布局,这样我们就可以直接通过布局id来控制对应按键的显隐状态,仔细阅读源码,我们能发现其实NavigationBarView给我们提供了现成的接口,只是这个接口并没有暴露出来给用户调用。接口名称如下,我们可以通过向接口中传递不同的参数来控制单个导航栏按键的使能状态。
NavigationBarView.setDisabledFlags(int disableStatus);
本人封装了一个方法来控制这些按键状态,具体实现如下:
/**
* @param keyId: keycode id(eg: KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_HOME, KeyEvent.KEYCODE_APP_SWITCH);
* @param enable: true: key enable; false: key disable.
*/
public void setKeyEnable(int keyId, boolean enable){
Intent intent = new Intent("android.intent.action.NAVGATIONBAR_CHANGED");
intent.putExtra("key_enabled", enable);
int enableStatus = enable? 1 : 0;
switch (keyId){
case KeyEvent.KEYCODE_BACK:
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.BACK_ENABLE, enableStatus);
intent.putExtra("key_code", KeyEvent.KEYCODE_BACK);
break;
case KeyEvent.KEYCODE_HOME:
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.HOME_ENABLE, enableStatus);
intent.putExtra("key_code", KeyEvent.KEYCODE_HOME);
break;
case KeyEvent.KEYCODE_APP_SWITCH:
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.SWITCH_ENABLE, enableStatus);
intent.putExtra("key_code", KeyEvent.KEYCODE_APP_SWITCH);
break;
}
mContext.sendBroadcast(intent);
}
Settings.java (frameworks\base\core\java\android\provider)
public static final class Secure extends NameValueTable {
…...
static {
…...
// modified by hubangming to make navigationbar button invisible, patch begin.
MOVED_TO_GLOBAL.add(Settings.Global.BACK_ENABLE);
MOVED_TO_GLOBAL.add(Settings.Global.HOME_ENABLE);
MOVED_TO_GLOBAL.add(Settings.Global.SWITCH_ENABLE);
// modified by hubangming, patch end.
}
public static final class Global extends NameValueTable {
…...
// modified by haming to make navigationbar button invisible, patch begin.
/**
* Enable the back key visible or invisible on navigationbar
* @hide
*/
public static final String BACK_ENABLE = "navigationbar_back_enable";
/**
* Enable the home key visible or invisible on navigationbar
* @hide
*/
public static final String HOME_ENABLE = "navigationbar_home_enable";
/**
* Enable the app_switch key visible or invisible on navigationbar
* @hide
*/
public static final String SWITCH_ENABLE = "navigationbar_switch_enable";
// modified by haming, patch end.
…...
}
PhoneStatusBar.java (frameworks\base\packages\systemui\src\com\android\systemui\statusbar\phone)
public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener {
…...
// modified by haming to make navigationbar button invisible, patch begin.
int disableStatus = 0;
//modified by haming, patch end.
…...
protected PhoneStatusBarView makeStatusBarView() {
…...
// modified by haming to make navigationbar button invisible, patch begin.
IntentFilter nvFilter = new IntentFilter();
nvFilter.addAction("android.intent.action.NAVGATIONBAR_CHANGED");
context.registerReceiver(mNavVisibleReceiver, nvFilter);
//modified by haming, patch end.
…...
}
// modified by haming to make navigationbar button invisible, patch begin.
private void setNavigationBarEnable(){
if(Settings.Global.getInt(mContext.getContentResolver(), "navigationbar_back_enable", 1) == 0){
disableStatus |= View.STATUS_BAR_DISABLE_BACK;
} else if (Settings.Global.getInt(mContext.getContentResolver(), "navigationbar_back_enable", 1) == 1){
disableStatus &= ~View.STATUS_BAR_DISABLE_BACK;
}
if(Settings.Global.getInt(mContext.getContentResolver(), "navigationbar_home_enable", 1) == 0){
disableStatus |= View.STATUS_BAR_DISABLE_HOME;
} else if(Settings.Global.getInt(mContext.getContentResolver(), "navigationbar_home_enable", 1) == 1){
disableStatus &= ~View.STATUS_BAR_DISABLE_HOME;
}
if(Settings.Global.getInt(mContext.getContentResolver(), "navigationbar_switch_enable", 1) == 0){
disableStatus |= View.STATUS_BAR_DISABLE_RECENT;
} else if(Settings.Global.getInt(mContext.getContentResolver(), "navigationbar_switch_enable", 1) == 1){
disableStatus &= ~View.STATUS_BAR_DISABLE_RECENT;
}
mNavigationBarView.setDisabledFlags(disableStatus);
}
// modified by haming, patch end.
// modified by haming to make navigationbar button invisible, patch begin.
private BroadcastReceiver mNavVisibleReceiver = new BroadcastReceiver(){
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("android.intent.action.NAVGATIONBAR_CHANGED".equals(action)) {
setNavigationBarEnable();
}
}
};
// modified by haming, patch end.
@Override
public void destroy() {
…...
// modified by haming to make navigationbar button invisible, patch begin.
mContext.unregisterReceiver(mNavVisibleReceiver);
// modified by haming, patch end.
}
}