Android快速设置中添加隐藏状态栏和导航栏选项
Android的状态栏和导航栏是在SystemUI中实现的,目前还不支持手动隐藏和显示状态栏和导航栏,接下来我们将对此功能进行讲解。
在系统启动过程中,会加载SystemUI中的状态栏,具体过程在这里不予以分析,状态栏对应的类为:\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBar.java
加载这个类会首先调用它的start方法。其代码为:
@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); } }
这个方法重写了父类\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\BaseStatusBar.java的start方法和调用了一个添加NavigationBar的方法,我们这里比较关心的是父类的这个start方法,来看看他的源码:
public void start() { mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); mDisplay = mWindowManager.getDefaultDisplay(); mDreamManager = IDreamManager.Stub.asInterface( ServiceManager.checkService(DreamService.DREAM_SERVICE)); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mProvisioningObserver.onChange(false); // set up mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true, mProvisioningObserver); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mRecents = getComponent(RecentsComponent.class); mLocale = mContext.getResources().getConfiguration().locale; mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale); // Connect in to the status bar manager service StatusBarIconList iconList = new StatusBarIconList(); ArrayList notificationKeys = new ArrayList(); ArrayList notifications = new ArrayList(); mCommandQueue = new CommandQueue(this, iconList); int[] switches = new int[7]; ArrayList binders = new ArrayList(); try { mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications, switches, binders); } catch (RemoteException ex) { // If the system process isn't there we're doomed anyway. } createAndAddWindows(); disable(switches[0]); setSystemUiVisibility(switches[1], 0xffffffff); topAppWindowChanged(switches[2] != 0); // StatusBarManagerService has a back up of IME token and it's restored here. setImeWindowStatus(binders.get(0), switches[3], switches[4]); setHardKeyboardStatus(switches[5] != 0, switches[6] != 0); // Set up the initial icon state int N = iconList.size(); int viewIndex = 0; for (int i=0; iif (icon != null) { addIcon(iconList.getSlot(i), i, viewIndex, icon); viewIndex++; } } // Set up the initial notification state N = notificationKeys.size(); if (N == notifications.size()) { for (int i=0; iget(i), notifications.get(i)); } } else { Log.wtf(TAG, "Notification list length mismatch: keys=" + N + " notifications=" + notifications.size()); } if (DEBUG) { Log.d(TAG, String.format( "init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x", iconList.size(), switches[0], switches[1], switches[2], switches[3] )); } mCurrentUserId = ActivityManager.getCurrentUser(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_SWITCHED); mContext.registerReceiver(mBroadcastReceiver, filter); }
这里实例化了一些服务类和管理类,并且对通知和系统图标做了一些初始化工作,其中调用了一个createAndAddWindows方法,这个方法做了哪些工作呢?这个一个抽象方法,那应该就是在其子类实现,我们回到PhoneStatusBar类中,果然有相应的实现
@Override public void createAndAddWindows() { addStatusBarWindow(); }
来看看addStatusBarWindow方法:
private void addStatusBarWindow() { // Put up the view final int height = getStatusBarHeight(); // Now that the status bar window encompasses the sliding panel and its // translucent backdrop, the entire thing is made TRANSLUCENT and is // hardware-accelerated. final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height, WindowManager.LayoutParams.TYPE_STATUS_BAR, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT); lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; lp.gravity = getStatusBarGravity(); lp.setTitle("StatusBar"); lp.packageName = mContext.getPackageName(); makeStatusBarView(); /// M: [SystemUI] For SystemUI AT. if (AutoTestHelper.isNotRunningInTest()) { mWindowManager.addView(mStatusBarWindow, lp); isStatusBarShow = true; } int state = Settings.System.getInt(mContext.getContentResolver(), Settings.System.STATUSBAR_HIDE, -1); if(state == 1){ mStatusBarWindow.setVisibility(View.GONE); mNavigationBarView.setVisibility(View.GONE); isStatusBarShow = false; } }
这里主要调用了makeStatusBarView这个方法,这个方法主要是用来构建状态栏的View
protected PhoneStatusBarView makeStatusBarView() {if (FeatureOption.MTK_GEMINI_SUPPORT) { mStatusBarWindow = (StatusBarWindowView)View.inflate(context, R.layout.gemini_super_status_bar, null);} else { mStatusBarWindow = (StatusBarWindowView) View.inflate(context, R.layout.super_status_bar, null);}mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar); // Quick Settings (where available, some restrictions apply) if (mHasSettingsPanel) { // first, figure out where quick settings should be inflated final View settings_stub; if (mHasFlipSettings) { // a version of quick settings that flips around behind the notifications settings_stub = mStatusBarWindow.findViewById(R.id.flip_settings_stub); if (settings_stub != null) { mFlipSettingsView = ((ViewStub)settings_stub).inflate(); mFlipSettingsView.setVisibility(View.GONE); mFlipSettingsView.setVerticalScrollBarEnabled(false); } } else { // full quick settings panel settings_stub = mStatusBarWindow.findViewById(R.id.quick_settings_stub); if (settings_stub != null) { mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate(); } else { mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel); } if (mSettingsPanel != null) { if (!ActivityManager.isHighEndGfx()) { mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor( R.color.notification_panel_solid_background))); } } } // wherever you find it, Quick Settings needs a container to survive mSettingsContainer = (QuickSettingsContainerView) mStatusBarWindow.findViewById(R.id.quick_settings_container); if (mSettingsContainer != null) { mQS = new QuickSettings(mContext, mSettingsContainer); if (!mNotificationPanelIsFullScreenWidth) { mSettingsContainer.setSystemUiVisibility( View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER | View.STATUS_BAR_DISABLE_SYSTEM_INFO); } if (mSettingsPanel != null) { mSettingsPanel.setQuickSettings(mQS); } mQS.setService(this); mQS.setBar(mStatusBarView); mQS.setup(mNetworkController, mBluetoothController, mBatteryController, mLocationController, mRotationLockController); } else { mQS = null; // fly away, be free } }
这里只列出了关键代码,实例化了一个mStatusBarView 对象,然后创建快速设置的显示面板,接着创建一个快速设置的容器,并利用这个容器来创建了一个QuickSettings对象,最后把这个对象添加到显示面板mSettingsPanel中,QuickSettings路径为:\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\QuickSettings.java
接下来QuickSettings对象mQS调用了setup方法,来看看这个方法:
void setup(NetworkController networkController, BluetoothController bluetoothController, BatteryController batteryController, LocationController locationController, RotationLockController rotationLockController) { mBluetoothController = bluetoothController; mRotationLockController = rotationLockController; mLocationController = locationController; setupQuickSettings(); updateResources(); applyLocationEnabledStatus(); /// M: We control BT state in QuickSettingsConnectionModel. ///networkController.addNetworkSignalChangedCallback(mModel); ///bluetoothController.addStateChangedCallback(mModel); batteryController.addStateChangedCallback(mModel); /// M: Support Laptop Battery on QS. batteryController.addLaptopStateChangedCallback(mModel); locationController.addSettingsChangedCallback(mModel); rotationLockController.addRotationLockControllerCallback(mModel); }
接着进入setupQuickSettings方法:
private void setupQuickSettings() { // Setup the tiles that we are going to be showing (including the temporary ones) LayoutInflater inflater = LayoutInflater.from(mContext); addUserTiles(mContainerView, inflater); addSystemTiles(mContainerView, inflater); addTemporaryTiles(mContainerView, inflater); IQuickSettingsPlugin quickSettingsPlugin = PluginFactory.getQuickSettingsPlugin(mContext); quickSettingsPlugin.customizeTileViews(mContainerView); queryForUserInformation(); queryForSslCaCerts(); mTilesSetUp = true; /// M: [SystemUI] Add quick settings function(airplane, data conn, bluetooth, timeout, gps, etc.) @{. mQuickSettingsConnectionModel.buildIconViews(); new Handler().postDelayed(new Runnable() { public void run() { setUpdate(); mQuickSettingsConnectionModel.setUpdates(true); mQuickSettingsConnectionModel.initConfigurationState(); } }, 200); /// M: [SystemUI] Add quick settings function(airplane, data conn, bluetooth, timeout, gps, etc.) @}. }
addUserTiles方法是添加快速设置中的用户选项,addSystemTiles方法添加了Wifi,蓝牙转屏等选项
private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) { /// M: MTK Quick Setting. addLaptopBatteryTile(parent, inflater); addBatteryTile(parent, inflater); addSettingTile(parent, inflater); addWifiTile(parent, inflater); addBluetoothTile(parent, inflater); addLocationTile(parent, inflater); addStatusBarTile(parent, inflater); addAirplaneTile(parent, inflater); addDataConnectionTile(parent, inflater); addDataUsageTile(parent, inflater); addAudioProfileTile(parent, inflater); addBrightnessTile(parent, inflater); addRotationTile(parent, inflater); addTimeoutTile(parent, inflater); }
在此,我们添加了一个addStatusBarTile方法,用于添加隐藏状态栏选项,代码为:
private void addStatusBarTile(ViewGroup parent, LayoutInflater inflater) { /// M: StatusBar Tile final QuickSettingsBasicTile statusBarTile = new QuickSettingsBasicTile(mContext, null, R.layout.mtk_quick_settings_tile_basic); statusBarTile.setTileViewId(QuickSettingsTileViewId.ID_StatusBar); parent.addView(statusBarTile); mQuickSettingsConnectionModel.addStatusBarTile(statusBarTile); }
这里首先声明了一个statusBarTile的view对象,然后设置了这个statusBarTile的显示的标题,再把这个statusBarTile对象添加到parent也就是mContainerView中,最后把statusBarTile添加到mQuickSettingsConnectionModel对象中,看看它的源码:
public void addStatusBarTile(View statusBarView) { mStatusBarTileView = statusBarView; mStatusBarLayout = (FrameLayout) mStatusBarTileView.findViewById(R.id.layout); mStatusBarIcon = (ImageView) mStatusBarTileView.findViewById(R.id.image); }
这里很简单,只是获取隐藏状态栏选项的view,布局和image。
回到setupQuickSettings方法中,接着会创建一个子线程,在这个子线程中会调用mQuickSettingsConnectionModel对象的initConfigurationState方法,看看源码:
public void initConfigurationState() { boolean isAirlineModeOn = isAirplaneModeOn(mContext); if (FeatureOption.MTK_WLAN_SUPPORT) { if (PluginFactory.getStatusBarPlugin(mContext).supportDisableWifiAtAirplaneMode()) { mWifiStateTracker.setAirlineMode(isAirlineModeOn); mWifiTileView.setEnabled(mWifiStateTracker.isClickable()); } mWifiStateTracker.setImageViewResources(mContext); } if (FeatureOption.MTK_BT_SUPPORT) { if (PluginFactory.getStatusBarPlugin(mContext).supportDisableBluetoothAtAirplaneMode()) { mBluetoothStateTracker.setAirlineMode(isAirlineModeOn); mBluetoothTileView.setEnabled(mBluetoothStateTracker.isClickable()); } mBluetoothStateTracker.setImageViewResources(mContext); } mAirlineModeStateTracker.setImageViewResources(mContext); /// M: only apply if NOT wifi-only device @{ if (!isWifiOnlyDevice()) { /// M: }@ mMobileStateTracker.setAirlineMode(isAirlineModeOn); mMobileStateTracker.setHasSim(false); mMobileStateTracker.setCurrentState(mContext, StateTracker.STATE_DISABLED); mMobileStateTracker.setImageViewResources(mContext); mSimCardReady = SystemProperties.getBoolean(TelephonyProperties.PROPERTY_SIM_INFO_READY, false); if (mSimCardReady) { Xlog.d(TAG, "Oops, sim ready, maybe phone is drop down and restarted"); List.SimInfoRecord> simInfos = SIMHelper.getSIMInfoList(mContext); if (simInfos == null || simInfos.size() <= 0) { mMobileStateTracker.setHasSim(false); } else { mMobileStateTracker.setHasSim(true); } mMobileTileView.setEnabled(mMobileStateTracker.isClickable()); mMobileStateTracker.setImageViewResources(mContext); } /// M: only apply if NOT wifi-only device @{ } /// M: }@ if (ENABLE_TIMEOUT) { mTimeoutStateTracker.setImageViewResources(mContext); } mAutoRotationStateTracker.setImageViewResources(mContext); mStatusBarStateTracker.setImageViewResources(mContext); if (ENABLE_AUDIO_PROFILE) { if (mProfileManager.getActiveProfileKey() != null) { updateProfileView(AudioProfileManager.getScenario(mProfileManager.getActiveProfileKey())); } } }
这个方法主要对快速设置栏中初始化的操作,我们在其中添加了mStatusBarStateTracker.setImageViewResources(mContext);
那么这个mStatusBarStateTracker是个什么呢?
它是QuickSettingsConnectionModel中的一个内部类的对象,
private final class StatusBarStateTracker extends StateTracker { @Override public int getActualState(Context context) { int state = Settings.System.getInt(context.getContentResolver(), Settings.System.STATUSBAR_HIDE, -1); if(state == -1){ state = 0; } if (state == 1) { return STATE_ENABLED; } else if (state == 0) { return STATE_DISABLED; } else { return STATE_UNKNOWN; } } @Override public void onActualStateChange(Context context, Intent unused) { /// M: Note: the broadcast location providers changed intent /// doesn't include an extras bundles saying what the new value is. setCurrentState(context, getActualState(context)); } @Override public void requestStateChange(final Context context, final boolean desiredState) { final ContentResolver resolver = context.getContentResolver(); new AsyncTask() { @Override protected Boolean doInBackground(Void... args) { Settings.System.putInt(context.getContentResolver(), Settings.System.STATUSBAR_HIDE, desiredState ? 1 : 0); return desiredState; } @Override protected void onPostExecute(Boolean result) { setCurrentState(context, result ? STATE_ENABLED : STATE_DISABLED); sendHideStatusBarBroadcast(result); } }.execute(); } public int getDisabledResource() { return R.drawable.ic_qs_mobile_off; } public int getEnabledResource() { return R.drawable.ic_qs_mobile_enable; } public ImageView getImageButtonView() { return mStatusBarIcon; } @Override public ImageView getIndicatorView() { return null; } public View getTileView() { return mStatusBarTileView; } }
这个内部类的作用主要就是获取并修改当前状态栏的状态(是否隐藏),具体的我们后面再分析。
在子线程中,其实还有setupQuickSettings方法的子线程中,还有一个方法我们没讲,mQuickSettingsConnectionModel.setUpdates(true);
来看看这个setUpdate方法:
public void setUpdates(boolean update) { if (update != mUpdating) { if (ENABLE_AUDIO_PROFILE) { mProfileKeys = new ArrayList(); mProfileKeys = mProfileManager.getPredefinedProfileKeys(); } mUpdating = update; if (update) { IntentFilter filter = new IntentFilter(); if (FeatureOption.MTK_WLAN_SUPPORT) { filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); } if (FeatureOption.MTK_BT_SUPPORT) { filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); } /// M: for mobile config filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); filter.addAction(TelephonyIntents.ACTION_SIM_INDICATOR_STATE_CHANGED); filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); filter.addAction(TRANSACTION_START); filter.addAction(TRANSACTION_STOP); filter.addAction(IPO_BOOT); filter.addAction(Intent.ACTION_BOOT_COMPLETED); refreshDataUsageTile(); mContext.registerReceiver(mIntentReceiver, filter); if (FeatureOption.MTK_GEMINI_SUPPORT) { mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.GPRS_CONNECTION_SIM_SETTING) , true, mMobileStateChangeObserver); } else { mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Global.MOBILE_DATA) , true, mMobileStateForSingleCardChangeObserver); } /// M: get notified of phone state changes TelephonyManager telephonyManager = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); if (FeatureOption.MTK_GEMINI_SUPPORT) { /// M: Support GeminiPlus for (int i = PhoneConstants.GEMINI_SIM_1; i < PhoneConstants.GEMINI_SIM_1 + PhoneConstants.GEMINI_SIM_NUM; i++) { SIMHelper.listen(mPhoneStateListenerGemini, PhoneStateListener.LISTEN_SERVICE_STATE, i); } } else { telephonyManager.listen(mPhoneStateListener1, PhoneStateListener.LISTEN_SERVICE_STATE); } mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.SCREEN_OFF_TIMEOUT), true, mTimeoutChangeObserver, mUserTracker.getCurrentUserId()); mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), true, mAutoRotationChangeObserver); mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.STATUSBAR_HIDE), true, mStatusBarChangeObserver); /// M: Register for Intent broadcasts for the clock and battery Xlog.d(TAG, "setUpdates: listenAudioProfie with mAudioProfileListenr = " + mAudioProfileListenr); if (ENABLE_AUDIO_PROFILE) { mProfileManager.listenAudioProfie(mAudioProfileListenr, AudioProfileListener.LISTEN_AUDIOPROFILE_CHANGEG); } } else { mContext.unregisterReceiver(mIntentReceiver); if (FeatureOption.MTK_GEMINI_SUPPORT) { mContext.getContentResolver().unregisterContentObserver( mMobileStateChangeObserver); } else { mContext.getContentResolver().unregisterContentObserver( mMobileStateForSingleCardChangeObserver); } TelephonyManager telephonyManager = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); if (FeatureOption.MTK_GEMINI_SUPPORT) { /// M: Support GeminiPlus for (int i = PhoneConstants.GEMINI_SIM_1; i < PhoneConstants.GEMINI_SIM_1 + PhoneConstants.GEMINI_SIM_NUM; i++) { SIMHelper.listen(mPhoneStateListenerGemini, 0, i); } } else { telephonyManager.listen(mPhoneStateListener1, 0); } mContext.getContentResolver().unregisterContentObserver(mTimeoutChangeObserver); mContext.getContentResolver().unregisterContentObserver(mAutoRotationChangeObserver); mContext.getContentResolver().unregisterContentObserver(mStatusBarChangeObserver); if (ENABLE_AUDIO_PROFILE) { mProfileManager.listenAudioProfie(mAudioProfileListenr, AudioProfileListener.LISTEN_NONE); } } } }
这里用到了ContentObserver内容观察者,用于监视快速设置中选项的变化,我们添加了如下代码:mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.STATUSBAR_HIDE),
true, mStatusBarChangeObserver);
来看看mStatusBarChangeObserver的实现:
private ContentObserver mStatusBarChangeObserver = new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { mStatusBarStateTracker.onActualStateChange(mContext, null); mStatusBarStateTracker.setImageViewResources(mContext); } };
当选项状态发生改变时,mStatusBarStateTracker对象就会获取当前的 状态,并对新的状态进行设置。我们接下来分析StatusBarStateTracker:
private final class StatusBarStateTracker extends StateTracker { @Override public int getActualState(Context context) { int state = Settings.System.getInt(context.getContentResolver(), Settings.System.STATUSBAR_HIDE, -1); if(state == -1){ state = 0; } if (state == 1) { return STATE_ENABLED; } else if (state == 0) { return STATE_DISABLED; } else { return STATE_UNKNOWN; } } @Override public void onActualStateChange(Context context, Intent unused) { /// M: Note: the broadcast location providers changed intent /// doesn't include an extras bundles saying what the new value is. setCurrentState(context, getActualState(context)); } @Override public void requestStateChange(final Context context, final boolean desiredState) { final ContentResolver resolver = context.getContentResolver(); new AsyncTask() { @Override protected Boolean doInBackground(Void... args) { Settings.System.putInt(context.getContentResolver(), Settings.System.STATUSBAR_HIDE, desiredState ? 1 : 0); return desiredState; } @Override protected void onPostExecute(Boolean result) { setCurrentState(context, result ? STATE_ENABLED : STATE_DISABLED); sendHideStatusBarBroadcast(result); } }.execute(); } public int getDisabledResource() { return R.drawable.ic_qs_mobile_off; } public int getEnabledResource() { return R.drawable.ic_qs_mobile_enable; } public ImageView getImageButtonView() { return mStatusBarIcon; } @Override public ImageView getIndicatorView() { return null; } public View getTileView() { return mStatusBarTileView; } }
当执行onActualStateChange方法时会执行setCurrentState方法,而执行setCurrentState又会调用requestStateChange方法,
public final void setCurrentState(Context context, int newState) { final boolean wasInTransition = mInTransition; switch (newState) { case STATE_DISABLED: mInTransition = false; mActualState = false; break; case STATE_ENABLED: mInTransition = false; mActualState = true; break; case STATE_TURNING_ON: mInTransition = true; mActualState = false; break; case STATE_TURNING_OFF: mInTransition = true; mActualState = true; break; default: break; } if (wasInTransition && !mInTransition) { if (mDeferredStateChangeRequestNeeded) { Xlog.v(TAG, "processing deferred state change"); if (mActualState != null && mIntendedState != null && mIntendedState.equals(mActualState)) { Xlog.v(TAG, "... but intended state matches, so no changes."); } else if (mIntendedState != null) { mInTransition = true; requestStateChange(context, mIntendedState); } mDeferredStateChangeRequestNeeded = false; } } }
在requestStateChange有个异步任务用于设置新的选项值,并发送一个广播,这个广播的作用是通知PhoneStatusBar可以隐藏或显示状态栏和导航栏了,
private void sendHideStatusBarBroadcast(boolean isStatusBarHide){ Intent intent = new Intent(); intent.putExtra("isStatusBarHide", isStatusBarHide); intent.setAction("com.android.hide_status_bar"); mContext.sendBroadcast(intent); }
接下来我们看看这个广播被接收后做了哪些处理。
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { else if (STATUS_BAR_HIDE_ACTION.equals(action)) { boolean isStatusBarHide = intent.getExtras().getBoolean("isStatusBarHide"); //Log.e("dy","isStatusBarHide == "+String.valueOf(isStatusBarHide)); //Log.e("dy","isStatusBarShow == "+String.valueOf(isStatusBarShow)); if(!isStatusBarHide){ mStatusBarWindow.setVisibility(View.VISIBLE); mNavigationBarView.setVisibility(View.VISIBLE); isStatusBarShow = true; Log.e("dy","show"); } if(isStatusBarHide){ mStatusBarWindow.setVisibility(View.GONE); mNavigationBarView.setVisibility(View.GONE); isStatusBarShow = false; Log.e("dy","hide"); } } else if (!isExpandedInvisible&&STATUS_BAR_HIDING_ACTION.equals(action)) { boolean isStatusBarHiding = intent.getExtras().getBoolean("isStatusBarHiding"); if(!isStatusBarHiding&&!isStatusBarShow){ mStatusBarWindow.setVisibility(View.VISIBLE); } if(isStatusBarHiding&&!isStatusBarShow){ mStatusBarWindow.setVisibility(View.GONE); } }}
这里其实挺简单,就是根据广播传过来的 属性 值,对状态栏和导航栏进行显示和隐藏。
Android快速设置中添加隐藏状态栏和导航栏选项的分析到此结束!
更多相关文章
- Android 链式调用(方法链)
- Android Activity之间切换出现短暂黑屏的处理方法
- Android开机启动Activity或者Service方法
- 【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介
- android语音识别方法示例代码
- Android下java方法和JS方法的互调
- Android 中LayoutInflater(布局加载器)源码篇之parseInclude方法