最近做客户项目,客户要求在设置中新增菜单来控制导航栏的显示与隐藏,由于之前在9.0上也有做过,所以就想当然认为也可以直接移植就OK,然后把补丁跟R的代码一对比,差别太大,完全没办法用。那好吧,老老实实读代码,看看该怎么加合适。 设置里面加菜单倒是简单,主要是如何隐藏跟显示导航栏这个不好搞。所以就花了点时间好好的梳理了一下导航栏加载跟显示的流程,梳理通顺后该改哪里该怎么改就水到渠成了。结果最重要,直接上代码吧。
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -171,6 +171,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
protected NavigationBarView mNavigationBarView = null;
+ //Added by qxbin@20210809
+ private static View mNavigationBarWindowView = null;
+ private ContentObserver mNavigationbarShowObserver;
+ //ending
+
private @WindowVisibleState int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
private int mNavigationIconHints = 0;
@@ -454,6 +459,17 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
Settings.System.getUriFor(Settings.System.SCREENSHOT_BUTTON_SHOW), true,
mScreenshotShowObserver, UserHandle.USER_ALL);
+ //Added by qxbin@20210809
+ mNavigationbarShowObserver = new ContentObserver( getContext().getMainThreadHandler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ mNavigationBarWindowView.setVisibility(Settings.System.getInt(mContentResolver, "show_navigartion_bar", 0) == 1 ? View.VISIBLE : View.GONE);
+ }
+ };
+
+ mContentResolver.registerContentObserver(Settings.System.getUriFor("show_navigartion_bar"), true, mNavigationbarShowObserver, UserHandle.USER_ALL);
+ //ending
+
if (savedInstanceState != null) {
@@ -488,6 +504,12 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
if(null != mScreenshotShowObserver){
mContentResolver.unregisterContentObserver(mScreenshotShowObserver);
}
+
+ //Added by qxbin@20210809
+ if(null != mNavigationbarShowObserver){
+ mContentResolver.unregisterContentObserver(mNavigationbarShowObserver);
+ }
+ //ending
}
@Override
@@ -1500,7 +1522,8 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
};
- public static View create(Context context, FragmentListener listener) {
+ //Modified by qxbin@20210809
+ /*public static View create(Context context, FragmentListener listener) {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
@@ -1543,7 +1566,59 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
});
context.getSystemService(WindowManager.class).addView(navigationBarView, lp);
return navigationBarView;
+ }*/
+
+ public static View create(Context context, FragmentListener listener) {
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
+ WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+ | WindowManager.LayoutParams.FLAG_SLIPPERY,
+ PixelFormat.TRANSLUCENT);
+ lp.token = new Binder();
+ lp.setTitle("NavigationBar" + context.getDisplayId());
+ lp.accessibilityTitle = context.getString(R.string.nav_bar);
+ lp.windowAnimations = 0;
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
+
+ mNavigationBarWindowView = LayoutInflater.from(context).inflate(
+ R.layout.navigation_bar_window, null);
+
+ if(Settings.System.getInt(context.getContentResolver(), "show_navigartion_bar", 0) == 1){
+ mNavigationBarWindowView.setVisibility(View.VISIBLE);
+ }else{
+ mNavigationBarWindowView.setVisibility(View.GONE);
+ }
+
+ if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarWindowView);
+ if (mNavigationBarWindowView == null) return null;
+
+ final NavigationBarFragment fragment = FragmentHostManager.get(mNavigationBarWindowView)
+ .create(NavigationBarFragment.class);
+ mNavigationBarWindowView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ final FragmentHostManager fragmentHost = FragmentHostManager.get(v);
+ fragmentHost.getFragmentManager().beginTransaction()
+ .replace(R.id.navigation_bar_frame, fragment, TAG)
+ .commit();
+ fragmentHost.addTagListener(TAG, listener);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ FragmentHostManager.removeAndDestroy(v);
+ mNavigationBarWindowView.removeOnAttachStateChangeListener(this);
+ }
+ });
+ context.getSystemService(WindowManager.class).addView(mNavigationBarWindowView, lp);
+ return mNavigationBarWindowView;
}
+ //ending
@VisibleForTesting
int getNavigationIconHints() {
关于设置里面的修改这里就不就啰嗦了。希望对大家有所帮助!
|