android SystemUI导航栏和状态栏-2020-12-02

目录

目录

1.推荐博客:

2.控制是否显示属性:qemu.hw.mainkeys​

3.调整大小:system/bigsystem/device/hisilicon/Hi3798MV200/overlay/frameworks/base/core/res/res/values/dimens.xml 

4.android6.0 TV 添加自定义导航栏

         5. 修改导航栏的背景色

         6.隐藏状态栏



1.推荐博客:

Android之SystemUI载入流程和NavigationBar的分析 - liguangsunls - 博客园

android6.0 TV 添加自定义导航栏_storm_peng的专栏-CSDN博客

android6.0 TV 添加自定义导航栏 - it610.com

2.控制是否显示属性:qemu.hw.mainkeys

3.调整大小:system/bigsystem/device/hisilicon/Hi3798MV200/overlay/frameworks/base/core/res/res/values/dimens.xml 

4.android6.0 TV 添加自定义导航栏

Android TV 通常是用遥控器操作的,系统导航栏都是关闭的,但带触摸的TV就很有必要加上导航栏了。

1. 修改base/core/res/res/values/config.xml 

 base/core/res/res/values/config.xml
 
-    <bool name="config_showNavigationBar">false</bool>
+    <bool name="config_showNavigationBar">true</bool>

但是在TV 上屏通常是横屏的,手机上是竖屏的,仅仅打开上面这个设置,在TV 右边屏幕就会有一个黑条的导航栏,但没有图标,这时候就要把导航栏想办法改到屏幕下面,

2. base/services/core/java/com/android/server/policy/PhoneWindowManager.java

mNavigationBarOnBottom这个值决定导航条的位置,从名字就看的出来,true 的时候是底部,false在垂直右边,在TV 屏的1920x1080分辨率上这个值 为false,所以直接改为true

主要代码在setInitialDisplaySize, 和beginLayoutLw 这两个函数里,包括导航栏的位置,其实X,Y 坐标,长宽等到

         public void setInitialDisplaySize(Display display, int width, int height, int density) {

         ......................................
        mNavigationBarCanMove = width != height && shortSizeDp < 600; 这个值在setInitialDisplaySize函数里

        ........................................

       public void beginLayoutLw(boolean isDefaultDisplay, int displayWidth, int displayHeight,
                              int displayRotation) {
        mNavigationBarOnBottom = true;//(!mNavigationBarCanMove || displayWidth < displayHeight);
                if (mNavigationBarOnBottom) {
                    // It's a system nav bar or a portrait screen; nav bar goes on bottom.
                    int top = displayHeight - overscanBottom //计算底部显示的 Y 坐标
                            - 100; //mNavigationBarHeightForRotation[displayRotation]; 这个值是导航栏的宽度,在setInitialDisplaySize计算出来是0,

                            实际Y 坐标top就是1080了,这 样看不到了导航栏了,这里直接改成100
                    mTmpNavigationFrame.set(0, top, displayWidth, displayHeight - overscanBottom); //设置导航栏位置大小
                 ................................
                } else { 
                    // Landscape screen; nav bar goes to the right.
                    int left = displayWidth - overscanRight //计算在右边显示 X 坐标
                            - mNavigationBarWidthForRotation[displayRotation];
                    mTmpNavigationFrame.set(left, 0, displayWidth - overscanRight, displayHeight);
                   ................................

这样导航栏的三个图标就出来了

3. 修改base/packages/SystemUI/res/layout/navigation_bar.xml 实现自定义布局

在base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java 文件的函数

   public void onFinishInflate() {        

         mRotatedViews[Surface.ROTATION_0] =          mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);

        mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90);

        mRotatedViews[Surface.ROTATION_270] = mRotatedViews[Surface.ROTATION_90];

        mCurrentView = mRotatedViews[Surface.ROTATION_0]; TV 实际用的这个,所以布局里就只修改

}

注意:原来的返回,主页,任务的三个图标,代码里面还会引用图片的名字。如果要替换,最好把要换的图片名字改成原来的一样,直接覆盖替换,否则代码里还要同步修改。

4. 修改按钮事件

layout 文件里每个KeyButtonView 下有一个systemui:keyCode="4",对应按键映射码,最终会在KeyButtonView 里取出来赋值给mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0); 在sendEvent 里虚拟一个按键事件把这个按键发送出去。对于其他新增加的按钮事件,可以找一个没用到的按键当作该按钮的按键,比如定义为KEYCODE_F1, 在navigation_bar.xml  里修改systemui:keyCode="131",再在PhoneWindow.java 的onKeyDown里添加下面代码,就可以在任何界面都能打开该activity了

case KeyEvent.KEYCODE_F1: {
      Intent itent = new Intent();
      itent.setClassName("com.supera.board", "com.supera.board.MainActivity");
      mContext.startActivity(itent);
      return true;
 }

最终的自定义导航栏就如下面的效果

5. 修改导航栏的背景色

在navigation_bar.xml  里有 android:background="@drawable/system_bar_background" 这一行,实际光修改这里是不起作用的,参考https://blog.csdn.net/kongbaidepao/article/details/82118406 这篇文章,屏蔽掉一行android6.0 TV 添加自定义导航栏_第1张图片

再修改 android:background="@drawable/system_bar_background" 就可以自定义背景颜色了

6. 修改导航栏的动态隐藏显示

参考https://blog.csdn.net/way_ping_li/article/details/45727335 修改后,隐藏没有问题,但手势滑不出来导航栏,经过查找发现SystemGesturesPointerEventListener.java 文件里的screenWidth ,screenHeight ,mSwipeStartThreshold 这是三个值都是0,导致在下面函数返回SWIPE_NONE

android6.0 TV 添加自定义导航栏_第2张图片

添加如下一段代码功能就正常手势滑开了

    public SystemGesturesPointerEventListener(Context context, Callbacks callbacks) {
       ..................
		WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); 
		screenWidth = wm.getDefaultDisplay().getWidth(); 
		screenHeight = wm.getDefaultDisplay().getHeight(); 

        mSwipeStartThreshold = 20;//checkNull("context", context).getResources()
................

6.隐藏状态栏 

frameworks/base/core/res/res/values/dimens.xml

1
2
<dimen name="status_bar_height">24dp</dimen>
<!-- Height of the bottom navigation / system bar. -->

将高度 24 改成 0   android 11上此方法只会隐藏顶部那部分UI,想要隐藏下拉的状态栏,还需要改动java代码如下:

framework/base/packages/SystemUI/src/android/systemui/statusbar/phone/StatusBar.java

makeStatusBarView函数设置 mStatusBarView.setVisibility(View.GONE);


    // ================================================================================
    // Constructing the view
    // ================================================================================
    protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
        final Context context = mContext;
        updateDisplaySize(); // populates mDisplayMetrics
        updateResources();
        updateTheme();

        inflateStatusBarWindow();
        mNotificationShadeWindowViewController.setService(this, mNotificationShadeWindowController);
        mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());

        // TODO: Deal with the ugliness that comes from having some of the statusbar broken out
        // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
        mStackScroller = mNotificationShadeWindowView.findViewById(
                R.id.notification_stack_scroller);
        NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
        mNotificationLogger.setUpWithContainer(notifListContainer);

        // TODO: make this injectable. Currently that would create a circular dependency between
        // NotificationIconAreaController and StatusBar.
        mNotificationIconAreaController = SystemUIFactory.getInstance()
                .createNotificationIconAreaController(context, this,
                        mWakeUpCoordinator, mKeyguardBypassController,
                        mStatusBarStateController);
        mWakeUpCoordinator.setIconAreaController(mNotificationIconAreaController);
        inflateShelf();
        mNotificationIconAreaController.setupShelf(mNotificationShelf);
        mNotificationPanelViewController.setOnReinflationListener(
                mNotificationIconAreaController::initAodIcons);
        mNotificationPanelViewController.addExpansionListener(mWakeUpCoordinator);

        mDarkIconDispatcher.addDarkReceiver(mNotificationIconAreaController);
        // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
        mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
        mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
        FragmentHostManager.get(mPhoneStatusBarWindow)
                .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
                    CollapsedStatusBarFragment statusBarFragment =
                            (CollapsedStatusBarFragment) fragment;

                    PhoneStatusBarView oldStatusBarView = mStatusBarView;
                    mStatusBarView = (PhoneStatusBarView) statusBarFragment.getView();
                    mStatusBarView.setBar(this);
                    mStatusBarView.setVisibility(View.GONE);
                    mStatusBarView.setPanel(mNotificationPanelViewController);
                    mStatusBarView.setScrimController(mScrimController);

                    statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
                    // CollapsedStatusBarFragment re-inflated PhoneStatusBarView and both of
                    // mStatusBarView.mExpanded and mStatusBarView.mBouncerShowing are false.
                    // PhoneStatusBarView's new instance will set to be gone in
                    // PanelBar.updateVisibility after calling mStatusBarView.setBouncerShowing
                    // that will trigger PanelBar.updateVisibility. If there is a heads up showing,
                    // it needs to notify PhoneStatusBarView's new instance to update the correct
                    // status by calling mNotificationPanel.notifyBarPanelExpansionChanged().
                    if (mHeadsUpManager.hasPinnedHeadsUp()) {
                        mNotificationPanelViewController.notifyBarPanelExpansionChanged();
                    }
                    mStatusBarView.setBouncerShowing(mBouncerShowing);
                    if (oldStatusBarView != null) {
                        float fraction = oldStatusBarView.getExpansionFraction();
                        boolean expanded = oldStatusBarView.isExpanded();
                        mStatusBarView.panelExpansionChanged(fraction, expanded);
                    }

                    HeadsUpAppearanceController oldController = mHeadsUpAppearanceController;
                    if (mHeadsUpAppearanceController != null) {
                        // This view is being recreated, let's destroy the old one
                        mHeadsUpAppearanceController.destroy();
                    }
                    // TODO: this should probably be scoped to the StatusBarComponent
                    // TODO (b/136993073) Separate notification shade and status bar
                    mHeadsUpAppearanceController = new HeadsUpAppearanceController(
                            mNotificationIconAreaController, mHeadsUpManager,
                            mNotificationShadeWindowView,
                            mStatusBarStateController, mKeyguardBypassController,
                            mKeyguardStateController, mWakeUpCoordinator, mCommandQueue,
                            mNotificationPanelViewController, mStatusBarView);
                    mHeadsUpAppearanceController.readFrom(oldController);

                    mLightsOutNotifController.setLightsOutNotifView(
                            mStatusBarView.findViewById(R.id.notification_lights_out));
                    mNotificationShadeWindowViewController.setStatusBarView(mStatusBarView);
                    checkBarModes();
                }).getFragmentManager()
                .beginTransaction()
                .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
                        CollapsedStatusBarFragment.TAG)
                .commit();

        mHeadsUpManager.setup(mVisualStabilityManager);
        mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView);
        mHeadsUpManager.addListener(this);
        mHeadsUpManager.addListener(mNotificationPanelViewController.getOnHeadsUpChangedListener());
        mHeadsUpManager.addListener(mVisualStabilityManager);
        mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
        mNotificationLogger.setHeadsUpManager(mHeadsUpManager);

        createNavigationBar(result);

        if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
            mLockscreenWallpaper = mLockscreenWallpaperLazy.get();
        }

        mKeyguardIndicationController.setIndicationArea(
                mNotificationShadeWindowView.findViewById(R.id.keyguard_indication_area));
        mNotificationPanelViewController.setKeyguardIndicationController(
                mKeyguardIndicationController);

        mAmbientIndicationContainer = mNotificationShadeWindowView.findViewById(
                R.id.ambient_indication_container);

        // TODO: Find better place for this callback.
        mBatteryController.addCallback(new BatteryStateChangeCallback() {
            @Override
            public void onPowerSaveChanged(boolean isPowerSave) {
                mHandler.post(mCheckBarModes);
                if (mDozeServiceHost != null) {
                    mDozeServiceHost.firePowerSaveChanged(isPowerSave);
                }
            }

            @Override
            public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
                // noop
            }
        });

        mAutoHideController.setStatusBar(new AutoHideUiElement() {
            @Override
            public void synchronizeState() {
                checkBarModes();
            }

            @Override
            public boolean shouldHideOnTouch() {
                return !mRemoteInputManager.getController().isRemoteInputActive();
            }

            @Override
            public boolean isVisible() {
                return isTransientShown();
            }

            @Override
            public void hide() {
                clearTransient();
            }
        });

        ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind);
        ScrimView scrimInFront = mNotificationShadeWindowView.findViewById(R.id.scrim_in_front);
        ScrimView scrimForBubble = mBubbleController.getScrimForBubble();

        mScrimController.setScrimVisibleListener(scrimsVisible -> {
            mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
            if (mNotificationShadeWindowView != null) {
                mLockscreenLockIconController.onScrimVisibilityChanged(scrimsVisible);
            }
        });
        mScrimController.attachViews(scrimBehind, scrimInFront, scrimForBubble);

        mNotificationPanelViewController.initDependencies(this, mGroupManager, mNotificationShelf,
                mNotificationIconAreaController, mScrimController);

        BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
        mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
                backdrop.findViewById(R.id.backdrop_back), mScrimController, mLockscreenWallpaper);
        float maxWallpaperZoom = mContext.getResources().getFloat(
                com.android.internal.R.dimen.config_wallpaperMaxScale);
        mNotificationShadeDepthControllerLazy.get().addListener(depth -> {
            float scale = MathUtils.lerp(maxWallpaperZoom, 1f, depth);
            backdrop.setPivotX(backdrop.getWidth() / 2f);
            backdrop.setPivotY(backdrop.getHeight() / 2f);
            backdrop.setScaleX(scale);
            backdrop.setScaleY(scale);
        });

        mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
        if (UserManager.get(mContext).isUserSwitcherEnabled()) {
            createUserSwitcher();
        }

        mNotificationPanelViewController.setLaunchAffordanceListener(
                mLockscreenLockIconController::onShowingLaunchAffordanceChanged);

        // Set up the quick settings tile panel
        final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
        if (container != null) {
            FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
            ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
                    mExtensionController
                            .newExtension(QS.class)
                            .withPlugin(QS.class)
                            .withDefault(this::createDefaultQSFragment)
                            .build());
            mBrightnessMirrorController = new BrightnessMirrorController(
                    mNotificationShadeWindowView,
                    mNotificationPanelViewController,
                    mNotificationShadeDepthControllerLazy.get(),
                    (visible) -> {
                        mBrightnessMirrorVisible = visible;
                        updateScrimController();
                    });
            fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
                QS qs = (QS) f;
                if (qs instanceof QSFragment) {
                    mQSPanel = ((QSFragment) qs).getQsPanel();
                    mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
                }
            });
        }

        mReportRejectedTouch = mNotificationShadeWindowView
                .findViewById(R.id.report_rejected_touch);
        if (mReportRejectedTouch != null) {
            updateReportRejectedTouchVisibility();
            mReportRejectedTouch.setOnClickListener(v -> {
                Uri session = mFalsingManager.reportRejectedTouch();
                if (session == null) { return; }

                StringWriter message = new StringWriter();
                message.write("Build info: ");
                message.write(SystemProperties.get("ro.build.description"));
                message.write("\nSerial number: ");
                message.write(SystemProperties.get("ro.serialno"));
                message.write("\n");

                PrintWriter falsingPw = new PrintWriter(message);
                FalsingLog.dump(falsingPw);
                falsingPw.flush();

                startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND)
                                .setType("*/*")
                                .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report")
                                .putExtra(Intent.EXTRA_STREAM, session)
                                .putExtra(Intent.EXTRA_TEXT, message.toString()),
                        "Share rejected touch report")
                                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
                        true /* onlyProvisioned */, true /* dismissShade */);
            });
        }

        if (!mPowerManager.isScreenOn()) {
            mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
        }
        mGestureWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
                "GestureWakeLock");
        mVibrator = mContext.getSystemService(Vibrator.class);
        int[] pattern = mContext.getResources().getIntArray(
                R.array.config_cameraLaunchGestureVibePattern);
        mCameraLaunchGestureVibePattern = new long[pattern.length];
        for (int i = 0; i < pattern.length; i++) {
            mCameraLaunchGestureVibePattern[i] = pattern[i];
        }

        // receive broadcasts
        registerBroadcastReceiver();

        IntentFilter demoFilter = new IntentFilter();
        if (DEBUG_MEDIA_FAKE_ARTWORK) {
            demoFilter.addAction(ACTION_FAKE_ARTWORK);
        }
        demoFilter.addAction(ACTION_DEMO);
        context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
                android.Manifest.permission.DUMP, null);

        // listen for USER_SETUP_COMPLETE setting (per-user)
        mDeviceProvisionedController.addCallback(mUserSetupObserver);
        mUserSetupObserver.onUserSetupChanged();

        // disable profiling bars, since they overlap and clutter the output on app windows
        ThreadedRenderer.overrideProperty("disableProfileBars", "true");

        // Private API call to make the shadows look better for Recents
        ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
    }

7.调整图标大小

Android P 禁止SystemUI 下拉状态栏和通知栏_逆风飞翔-CSDN博客

https://blog.csdn.net/jydzm/article/details/88745335

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值