在android11 上实现平行视界效果

前言:

平行视界是谷歌为了解决大屏横屏设备 适配为手机等竖屏设备开发的APP , 在这类APP显示时 在横屏设备上不方便用户观看。

android 13 上平行视界的效果如下:

正文:

在android13前 ,各家有各自的解决方案,下面提供一种实现方案,如下:

frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

+    // ---------#--------------#-----------
+    // |        #              #          |
+    // |        #              #          |
+    // |        #              #          |
+    // |        #              #          | 如果 显示器是横屏, app 是竖屏 , 则将显示的宽高 等比例缩放
+    // |        #              #          |
+    // |        #              #          |
+    // ---------#--------------#-----------
     private DisplayInfo updateDisplayAndOrientation(int uiMode, Configuration outConfig) {
         // Use the effective "visual" dimensions based on current rotation
         final int rotation = getRotation();
         final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
-        final int dw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
-        final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
-
+//         如果 显示器是横屏, app 是竖屏 , 则将显示的宽高 等比例缩放
+//        final int dw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
+//        final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
+        int dw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
+        int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
+        if( SystemProperties.getBoolean("persist.sys.landspace.display.portrait.app.enabled", false) ) {
+            int appOrientation = getOrientation();
+            if( rotated && appOrientation==ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ){
+                dw = mBaseDisplayWidth*mBaseDisplayWidth/mBaseDisplayHeight;
+                dh = mBaseDisplayWidth;
+                Slog.d(TAG, "修改显示大小 dw "+dw +" dh "+dh );
+            }
+        }
         // Update application display metrics.
         final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation);
         final DisplayCutout displayCutout = wmDisplayCutout.getDisplayCutout();
@@ -4015,6 +4035,17 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
         int height = displayInfo.logicalHeight;
         int top = (physHeight - height) / 2;
         out.set(left, top, left + width, top + height);
+
+//        在display 是横屏, app 是竖屏时  计算 window 的边框
+        if( SystemProperties.getBoolean("persist.sys.landspace.display.portrait.app.enabled", false) ) {
+            int appOrientation = getOrientation();
+            if( rotated && appOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ){
+                int appWidth = mBaseDisplayWidth*mBaseDisplayWidth/mBaseDisplayHeight;
+                int appHeight = mBaseDisplayWidth;
+                out.set(0, 0, appWidth, appHeight);
+                Slog.d(TAG, "计算window Bounds "+out);
+            }
+        }
     }

frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java

@@ -1191,6 +1213,14 @@ public class DisplayRotation {
                 if (isAnyPortrait(preferredRotation)) {
                     return preferredRotation;
                 }
+//                app 请求竖屏 ,display 修改返回横屏
+                if( SystemProperties.getBoolean("persist.sys.landspace.display.portrait.app.enabled", false) ) {
+                    if( sensorRotation == Surface.ROTATION_90  ){
+                        return  mLandscapeRotation;
+                    }else if(  sensorRotation == Surface.ROTATION_270){
+                        return  mSeascapeRotation;
+                    }
+                }
                 return mPortraitRotation;
 
             case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:

实现uniapp的自适应和平行视界效果,可以使用以下代码: ``` <template> <div class="container"> <div class="content"> <!-- 内容区域 --> </div> </div> </template> <style> .container { width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; perspective: 1000px; /* 视角距离 */ } .content { width: 100%; max-width: 800px; /* 内容最大宽度 */ margin: 0 auto; transform-style: preserve-3d; transform: rotateY(var(--rotate-y, 0deg)); /* 动态设置旋转角度 */ transition: transform 0.5s ease-in-out; /* 动画过渡效果 */ } </style> <script> export default { name: "App", mounted() { // 监听窗口大小变化 window.addEventListener("resize", this.handleResize); this.handleResize(); }, beforeDestroy() { // 移除窗口大小变化监听 window.removeEventListener("resize", this.handleResize); }, methods: { handleResize() { // 获取屏幕宽度 const screenWidth = window.innerWidth || document.documentElement.clientWidth; // 计算旋转角度 const rotateY = screenWidth >= 1200 ? "-30deg" : "0deg"; // 设置旋转角度 document.documentElement.style.setProperty("--rotate-y", rotateY); } } }; </script> ``` 上述代码中,我们使用了flex布局和perspective属性来实现平行视界效果。在mounted钩子函数中,我们监听窗口大小变化,动态计算旋转角度并设置到根元素上,从而实现自适应和平行视界效果。在样式中,我们使用transform-style和transform属性来控制元素的3D变换,使用transition属性来实现动画过渡效果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值