Android系统屏蔽滑动出现导航栏和通知栏

Android系统屏蔽滑动出现导航栏和通知栏

需求

某些应用在定制系统内需要维持全屏显示,需要屏蔽滑动上拉出现导航栏和下拉出现通知栏,而且还需要屏蔽手势导航。

系统版本

Android 13

准备工作

知道需要屏蔽操作的应用包名,例如:com.example.myapp

修改涉及到的文件

主要涉及到以下目录的文件

/packages/apps/Launcher3/quickstep/src/com/android/quickstep/TouchInteractionService.java
/frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.java
/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java

修改步骤

  1. 屏蔽手势导航

TouchInteractionService文件中的onInputEvent方法添加判断包名,然后不去响应手势事件。

private void onInputEvent(InputEvent ev) {
	......
	......
	......
	if (action == ACTION_DOWN) {
        mRotationTouchHelper.setOrientationTransformIfNeeded(event);

        // if the task is myapp, don't consumer gesture
+        if (mAM.getRunningTask() != null && mAM.getRunningTask().topActivity != null
+                && "com.example.myapp".equals(mAM.getRunningTask().topActivity.getPackageName())) {
+            mUncheckedConsumer = InputConsumer.NO_OP;
+        } else if (!mDeviceState.isOneHandedModeActive()
                    && mRotationTouchHelper.isInSwipeUpTouchRegion(event)) {
         // Clone the previous gesture state since onConsumerAboutToBeSwitched might trigger
            // onConsumerInactive and wipe the previous gesture state
            GestureState prevGestureState = new GestureState(mGestureState);
            GestureState newGestureState = createGestureState(mGestureState);
            newGestureState.setSwipeUpStartTimeMs(SystemClock.uptimeMillis());
            mConsumer.onConsumerAboutToBeSwitched();
            mGestureState = newGestureState;
            mConsumer = newConsumer(prevGestureState, mGestureState, event);
            mUncheckedConsumer = mConsumer;
        } else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode()
                && mDeviceState.canTriggerAssistantAction(event)) {
            mGestureState = createGestureState(mGestureState);
            // Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we
            // should not interrupt it. QuickSwitch assumes that interruption can only
            // happen if the next gesture is also quick switch.
            mUncheckedConsumer = tryCreateAssistantInputConsumer(mGestureState, event);
        } else if (mDeviceState.canTriggerOneHandedAction(event)) {
            // Consume gesture event for triggering one handed feature.
            mUncheckedConsumer = new OneHandedModeInputConsumer(this, mDeviceState,
                    InputConsumer.NO_OP, mInputMonitorCompat);
        } else {
            mUncheckedConsumer = InputConsumer.NO_OP;
        }
    } else {
        // Other events
        if (mUncheckedConsumer != InputConsumer.NO_OP) {
            // Only transform the event if we are handling it in a proper consumer
            mRotationTouchHelper.setOrientationTransformIfNeeded(event);
        }
    }
   	......
	......
	......      
}      
  1. 屏蔽上拉出现导航栏

同样在DisplayPolicy文件中添加判断包名的方法,从而不去执行操作。

+boolean isMyApp() {
+    try {
+        ActivityTaskManager activityTaskManager = ActivityTaskManager.getInstance();
+        List<ActivityManager.RunningTaskInfo> runningTaskInfoList =
+                activityTaskManager.getTasks(1);
+
+        if (runningTaskInfoList == null || runningTaskInfoList.isEmpty()) {
+            Slog.i(TAG, "No running task found!");
+            return false;
+        }
+
+        ActivityManager.RunningTaskInfo runningTaskInfo = runningTaskInfoList.get(0);
+
+        ComponentName topActivity = runningTaskInfo.topActivity;
+        if (topActivity == null) {
+            Slog.i(TAG, "No topActivity!");
+            return false;
+        }
+
+        if ("com.example.myapp".equals(topActivity.getPackageName())) {
+            return true;
+        }
+    } catch (Exception e) {
+        Slog.e(TAG, e.getMessage());
+    }
+    return false;
+}

@VisibleForTesting
void requestTransientBars(WindowState swipeTarget, boolean isGestureOnSystemBar) {
    // if running task is myapp, don't transient bars
+    if (isMyApp()) {
+        return;
+    }
    ......
	......
	...... 
}	
  1. 屏蔽滑动下拉出现通知栏

CommandQueue文件中的panelsEnabled方法添加判断包名,从而不使能状态栏下拉操作。

public boolean panelsEnabled() {
+    ActivityManagerWrapper mAM = ActivityManagerWrapper.getInstance();
+    if (mAM.getRunningTask() != null && mAM.getRunningTask().topActivity != null
+            && "com.example.myapp".equals(mAM.getRunningTask().topActivity.getPackageName())) {
+        return false;
+    } else {
        final int disabled1 = getDisabled1(mDisplayTracker.getDefaultDisplayId());
        final int disabled2 = getDisabled2(mDisplayTracker.getDefaultDisplayId());
        return (disabled1 & StatusBarManager.DISABLE_EXPAND) == 0
                && (disabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0;
+    }
}

总结

以上就是Android系统屏蔽滑动出现导航栏和通知栏,并且不响应手势导航的方法。

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以通过在 RecyclerView 外部嵌套一个带有滑动导航栏的布局来实现这个效果。具体步骤如下: 1. 在布局文件中创建一个带有滑动导航栏的布局,例如使用 TabLayout 和 ViewPager2 实现: ```xml <com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabGravity="center" app:tabMode="scrollable" /> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 在代码中初始化 TabLayout 和 ViewPager2,并设置 Adapter: ```kotlin val tabLayout: TabLayout = findViewById(R.id.tab_layout) val viewPager: ViewPager2 = findViewById(R.id.view_pager) val adapter = MyAdapter(supportFragmentManager, lifecycle) viewPager.adapter = adapter TabLayoutMediator(tabLayout, viewPager) { tab, position -> tab.text = "Tab ${position + 1}" }.attach() ``` 3. 在 Adapter 中创建 RecyclerView,并在 onCreateViewHolder 中返回 ViewHolder: ```kotlin override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { if (viewType == TYPE_RECYCLER_VIEW) { val view = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_layout, parent, false) return RecyclerViewHolder(view) } else { val view = LayoutInflater.from(parent.context).inflate(R.layout.view_pager_layout, parent, false) return ViewPagerHolder(view) } } ``` 4. 在 RecyclerView 的 Adapter 中添加一个 header item,用来显示滑动导航栏,例如: ```kotlin override fun getItemViewType(position: Int): Int { return if (position == 0) TYPE_HEADER else TYPE_RECYCLER_VIEW } override fun getItemCount(): Int { return list.size + 1 // 添加一个 header item } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { if (holder is RecyclerViewHolder) { val item = list[position - 1] // 减去 header item holder.bind(item) } } ``` 5. 在 RecyclerView 的 LayoutManager 中,设置偏移量来使 RecyclerView 的内容不会被滑动导航栏遮挡: ```kotlin val layoutManager = LinearLayoutManager(this) recyclerView.layoutManager = layoutManager recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() { override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { super.getItemOffsets(outRect, view, parent, state) if (parent.getChildAdapterPosition(view) == 0) { outRect.top = tabLayout.height } } }) ``` 这样,你就可以在 RecyclerView 中添加一个顶部滑动导航栏了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值