自学内容网 自学内容网

android 11添加切换分屏功能

引言

自Android 7开始官方就支持分屏显示,但没有切换分屏的功能,即交换上下屏幕。直到Android 13开始才支持切换分屏,操作方式是:分屏模式下双击中间分割线就会交换上下屏位置。本文的目的就是在Android 11上实现切换分屏的功能。

下图是Android13切换分屏演示
android 13 toggleSplitScreen

切换分屏原理说明

systemui启动后就会创建属于分屏模式的两个任务栈,一个StackId=3且mode=split-screen-primary表示上半屏任务栈,显示位置为bounds=[0,0][720,606],一个StackId=4且mode=split-screen-secondary表示下半屏任务栈,显示位置为bounds=[0,626][720,1280]。
要交换上下屏显示,只需要修改下两个任务栈(即bounds)的显示位置即可,修改方式通过修改任务栈关联的SurfaceControl的position和bounds。

修改实现

因为Android13和Android14切换分屏操作是双击中间的分割线,因此我们参看他们的也实现同样的功能。
我这里有android14的代码,我们来看看android14的关键部分:

android14双击分屏分割线代码调用路径
DoubleTapListener.onDoubleTap(MotionEvent e)
mSplitLayout.onDoubleTappedDivider()
mSplitLayoutHandler.onDoubleTappedDivider()
switchSplitPosition("double tap")

switchSplitPosition方法在StageCoordinator.java类里
在这里插入图片描述
实现分屏交换的就是红框里的方法。

关键地方找到了就好办了,下面是我在android11上的修改,主要的修改类:

frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java

修改如下:

diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index b6c6afd523b3..981bab3263e4 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -25,7 +25,10 @@ import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.res.Configuration;
 import android.graphics.Matrix;
 import android.graphics.Rect;
@@ -36,8 +39,10 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.Slog;
 import android.view.Display;
+import android.view.GestureDetector;
 import android.view.MotionEvent;
 import android.view.PointerIcon;
 import android.view.SurfaceControl;
@@ -55,6 +60,8 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
+import android.window.WindowContainerTransaction;
+import android.window.WindowOrganizer;
 
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.internal.logging.MetricsLogger;
@@ -77,6 +84,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
         OnComputeInternalInsetsListener {
   
     private static final String TAG = "DividerView";
     private static final boolean DEBUG = Divider.DEBUG;
+    private GestureDetector mDoubleTapDetector;
+    boolean mToggleSplitScreen;
 
     public interface DividerCallbacks {
   
         void onDraggingStart();
@@ -175,6 +184,16 @@ public class DividerView extends FrameLayout implements OnTouchListener,
 
     private final Handler mHandler = new Handler();
 
+    private static final String ACTION_TOGGLE_SPLIT_SCREEN = "action_toggle_split_screen";
+    private BroadcastReceiver mToggleSplitScreenReceiver = new BroadcastReceiver() {
   
+        @Override
+        public void onReceive(Context context, Intent intent) {
   
+            if (intent.getAction().equals(ACTION_TOGGLE_SPLIT_SCREEN)){
   
+                toggleSplitScreen("receive toggle_split_screen broadcast");
+            }
+        }
+    };

原文地址:https://blog.csdn.net/u014763302/article/details/144005677

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!