小米大屏设备适配说明1

1、概述

1.1 小米大屏设备介绍

1.1.1 折叠屏形态与尺寸

折叠屏是一种柔性屏,可以进行弯曲、折叠,比如上下折叠,左右折叠等。

Xiaomi MIX Fold 和 Xiaomi MIX Fold 2 均为左右内折叠设备,其展开状态和折叠状态屏幕大小和分辨率如下:

外屏内屏
尺寸分辨率尺寸分辨率
Xiaomi MIX Fold6.52英寸2520×8408.01英寸2480×1860
Xiaomi MIX Fold 26.56英寸2520×10808.02英寸2160×1914

判断是否为折叠屏设备的接口为:

//可通过反射调用 SystemProperties 的 persist.sys.muiltdisplay_type 属性值来进行判断
boolean isFoldDisplay = SystemProperties.getInt("persist.sys.muiltdisplay_type", 0) == 2;

折叠/展开态的判断接口为:

// 0 UNKNOWN
// 1 折叠
// 2 半折(MIX Fold 2支持)
// 3 展开
final int posture = Settings.Global.getInt(this.getContentResolver(), "device_posture", 0);

1.1.2 平板设备形态与尺寸

小米平板设备屏幕大小和分辨率信息如下:

尺寸分辨率
小米平板511 英寸2560 x 1600
小米平板5 Pro11 英寸2560 x 1600
小米平板5 Pro 5G11 英寸2560 x 1600
小米平板5 Pro 12.412.4 英寸2560 x 1600

判断是否为平板设备的接口为:

public static boolean isTablet(){    
/**应用需反射调用*/    
     return SystemProperties.get("ro.build.characteristics").contains("tablet");}

应用也可以动态判断当前窗口显示在大屏下:

public static boolean isTablet(Context context) {    
    return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;}

1.1.3 可扩展性

小米大屏设备品类形态未来将会有更多丰富的产品,因此应用适配后需要支持一定程度拉伸。

1.2 文档适用对象

需要适配小米大屏设备应用的第三方开发者、UX设计师、系统工程师、测试

2、UX设计与软件形态适配建议

2.1 基础体验设计

2.1.1 字体

  • 优先调用系统默认字体来保证整台设备的阅读体验一致性,除非有特殊需求;
  • 排版及字号字重应保证清晰可读;
  • 在折叠屏上,建议保持内外屏字号大小一致,展开大屏字号大小如要放大,最大不能超过外屏小屏的1.2倍。

2.1.2 图片、视频

  • 这些资源不应该出现变形、模糊或者显示不全的问题,影响体验;
  • 在折叠屏上,建议图片、视频等信息内容在内外屏采用动态布局,保持图片视频等内容大小一致;展开大屏的图片视频等内容大小如要放大,最大不能超过屏幕高度。

2.1.3 弹窗

  • 弹窗在应用设计中比较常见,如运营内容、广告营销等,建议弹窗大小适中,且有清晰的供用户关闭的按钮;
  • 在折叠屏上,建议弹窗大小内外屏保持一致;展开大屏的弹窗如要放大,最大不能超过屏幕高度的70%。

2.2 页面布局设计

2.2.1 动态布局

  • 大屏设备能够在竖屏和横屏之间无缝切换,折叠屏设备还能够在内屏和外屏之间无缝切换,拥有强大的功能和内容体验。
  • 应用可能会遇到以下几种窗口情况

基于以上情况,推荐几种布局方式

A.拉伸

仅卡片区域、显示区域等拉伸,文字大小图标大小均保持一致

B.缩放

根据窗口区域等比缩放内容信息

C.拓展/增量/减量

根据窗口区域增加或减少项,项的尺寸大小保持不变

D.重新布局

根据窗口区域重新对内容进行布局,以适应更好的信息阅读

vivo 折叠屏三方应用开发适配指南

一、vivo 多窗口(分屏小窗)功能适配指南

1.1 适配背景

随着大屏手机的普及,用户对于多窗口功能的使用越来越频繁,尽管google 已经推出了多窗口功能,但是很多应用还没有适配多窗口功能,因此,我们输出《vivo 多窗口(分屏小窗)功能适配指南》提供给应用侧进行适配,让三方应用开发者能够更清楚多窗口功能的适配开发流程。

1.2 适配指导

1.2.1 配置支持多窗口功能

应用AndroidManifest.xml 中可以针对 app 或 activity 进行设置。

代码实例:

<application
  android:resizeableActivity="true">
  <activity
      android:resizeableActivity="true" />
</application>

当应用 targetSdkVersion >=24 时,android 系统默认设置 android:resizeableActivity=”true”,不需要应用声明即可支持应用使用多窗口功能。当应用 targetSdkVersion < 24 时,需要应用针对 application 或 activity 设置 android:resizeableActivity=”true”。

1.2.2 获取Activity 实际显示的窗口大小和位置

Android11 及以上(API 级别为30 及以上)推荐使用:

WindowManager#getCurrentWindowMetrics() : 针对系统的当前窗口状态, 返回WindowMetrics 对象

WindowManager#getMaximumWindowMetrics():针对系统可能的最大窗口状态,返回 WindowMetrics

代码实例:

获取当前activity 的窗口指标

WindowMetrics windowMetrics = activity.getWindowManager().getCurrentWindowMetrics();

Android10(API 级别为29)推荐使用:

context.getResources().getDisplayMetrics()

不推荐使用:

context.getWindowManager().getDefaultDisplay().getMetrics(outMetrics)

上述接口中,context 为 Activity 对应的上下文句柄,每个 Activity 应该严格使用自己的context 来进行布局,而不是使用 application 的 context。

备注:

Display 方法 getSize() 和 getMetrics() 在 API 级别 30 中已被弃用,取而代之的是新的 WindowManager# getCurrentWindowMetrics() 方法。

Android 12(API 级别 31)弃用了 Display 方法 getRealSize() 和 getRealMetrics(),并更新了它们的行为以使其更接近 getMaximumWindowMetrics() 的行为。

getSize():获取context 显示的尺寸,不包括状态栏等系统显示区域的尺寸

getRealSize():获取手机屏幕的真实尺寸,包括状态栏等系统显示区域的尺寸

getMetrics():获取context 显示区域的屏幕元素,例如屏幕尺寸、屏幕密度等屏幕元素信息,不包括状态栏等系统显示区域的屏幕元素信息

getRealMetrics():获取context 显示区域的屏幕元素信息,例如屏幕尺寸、屏幕密度等屏幕元素信息,包括状态栏等系统显示区域的屏幕元素信息

Android10 上,我们推荐使用getSize 和getMetrics 来获取显示区域的大小。在多窗口(分屏小窗)模式下,getSize 和getMetrics 获取出来的是context 显示区域的大小,getRealSize和getRealMetrics 获取出来的是手机屏幕的真实大小,getSize 和getMetrics 获取出来的尺寸值要小于getRealSize 和getRealMetrics 的尺寸值。

1.2.3 获取Activity 的窗口布局方向

获取Activity 窗口方向的的方法为:

context.getResources().getConfiguration().orientation

注:不要使用width /height 的方法来判Activity 为横竖屏布局,因为在多窗状态下,支持应用的拖动,会改变宽高。

获取设备方向的方法如下:

context.getWindowManager().getDefaultDisplay().getRotation()。

1.2.4 Activity 大小切换时不重启适配

1. 应用在Activity 窗口大小切换时不重启适配,在android:configChanges 属性增加 screenSize|screenLayout| orientation|smallestScreenSize

代码示例:

<activity
 android:name=".MyActivity"
 android:configChanges="screenSize | smallestScreenSize | screenLayout | orientation" />

2. 在Activity 的onConfigurationChanged 回调中更新宽高刷新子布局。

代码示例:

@Override
public void onConfigurationChanged(Configuration newConfig) {
   super.onConfigurationChanged(newConfig);
   ……
}

应用复写 onConfigurationChanged() 方法,通过该方法的 Configuration 参数获得窗口高度等信息,并对界面布局做相应调整,如切换布局、调整控件位置和间距等。

1.2.5 状态栏位置

当处于分屏下屏,和小窗模式时,应用没有状态栏,此时不应该留出状态栏高度,需要从顶部开始布局。

可以通过configuration 中windowingmode 判断当前处于的模式,WINDOWING_MODE_FREEFORM 和WINDOWING_MODE_SPLIT_SCREEN_SECONDARY 不需要空出状态栏。

1.2.6 分屏下ActivityRecord 动画问题

很多应用会重写

<item name="android:activityOpenEnterAnimation">@null</item>
<item name="android:activityOpenExitAnimation">@null</item>
<item name="android:activityCloseEnterAnimation">@null</item>
<item name="android:activityCloseExitAnimation">@null</item>

分屏下containingWidth/containingHeight 为分屏窗口的尺寸, width/height 为displaycontent 尺寸(全屏)

initialize(containingWidth, containingHeight, width, height);

对于动画类型有 ABSOLUTE/RELATIVE_TO_SELF/RELATIVE_TO_PARENT

如果应用配置的xml 中带了p,使用的displaycontent 尺寸,会导致分屏下位移动画问题。没有p 为 RELATIVE_TO_SELF 类型

1.2.7 正确处理分屏小窗的沉浸式

分屏或小窗模式下,应用顶部有个功能bar,应用在沉浸式适配时需为此功能bar 预留一定空间。因此应用在布局时,需要监听安卓原生的WindowInsetsListener 接口回调,针对captionBarInsets 变化来处理view 高度,注意不要使用固定高度!!!

参考代码:

java:

getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> {
  //应用在回调中计算view 高度
  return insets;
});

kotlin:

window.decorView.setOnApplyWindowInsetsListener { v: View?, insets: WindowInsets ->
  //应用在回调中计算view 高度
  insets
}

1.2.8 其他布局建议

•  布局参数尽量使用相对的布局参数,不要使用固定尺寸

•  避免根据屏幕大小,输入法高度等计算view 的布局参数,如设置popwindow、dialog 等子窗口的位置时,避免使用整个屏幕的相对位置

•  避免对DecorView,content 等根布局进行定制,比如设置DecorView 的背景、在DecorView 添加子布局等

•  注意生命周期处理,如小窗模式下出现页面点击、拖动无响应问题,可能跟布局或生命周期有关

•  避免根据物理屏幕方向设置当前功能或布局

二、折叠屏前后屏切换适配指南

2.1 屏幕兼容性

2.1.1 应用布局优化

折叠屏有主屏(展开态)和副屏(折叠态)两种形态,以X Fold 为例,主屏和副屏的分辨率分别是1916×2160 和1080×2520,densityDpi 是480,应用程序需要针对不同的屏幕尺寸进行布局适配和优化。

2.1.1.1 屏幕兼容显示

在对不同尺寸屏幕适配过程中,为了确保在折叠屏各个屏幕形态下获取最佳的布局显示效果,例如页面无明显的拉伸放大、布局错位、重叠和显示更多更清晰的内容,建议您对布局进行优化。应用界面正确、美观的布局和显示,包含如下:

•  确保您的布局能够根据屏幕适当地调整大小

•  根据屏幕配置提供合适的 UI 布局

•  确保对正确的屏幕应用正确的布局

•  提供可正常缩放的位图

    详细适配方法请参考Android 开发者适配指导:https://developer.android.com/training/multiscreen/screensizes?hl=zh-cn

    基于折叠屏的特性,用户经常会在主屏(大屏)玩游戏或全屏看视频,以X Fold 为例,主屏有前置摄像头,因此应用程序页面需要针对打孔屏做适配,避免页面显示时摄像头区域出现白边或黑边,影响显示效果。参考vivo 手机全屏适配开发指导:https://developers.vivo.com/doc/d/52a902cf33fa72efeeeaf5197d60efa5

2.1.1.2 支持横竖屏切换

以X Fold 为例,主屏(展开态)屏幕尺寸接近4:3,桌面应用支持横竖屏显示,因此用户会在任何形态下打开应用。因此我们建议应用程序支持横竖屏切换,提高用户体验。横竖屏切换适配建议如下:

1、 横竖屏切换涉及到方向、尺寸和键盘隐藏/ 显示, 因此需要在Activity 配置

android:configChanges=”orientation|screenSize|screenLayout|smallestScreenSize|keyboard|keyboardHidden”

2、 在onConfigurationChanged 函数收到config 变化后,动态加载横竖屏布局以及完成其他任务

public void onConfigurationChanged(Configuration newConfig) {
   super.onConfigurationChanged(newConfig);
   if(newConfig.orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
      //switch to port and load layout
      setContentView(R.layout.activity_main);
      //TODO something
   }else{
      //switch to land and load layout
      setContentView(R.layout.activity_main_land);
      //TODO something
   }
}

2.1.2 应用resizeable 能力支持

折叠屏状态切换时,涉及到分辨率和像素密度的动态变化。若应用程序界面不支持resizeable 能力,在切屏时会存在应用程序界面未全屏显示的问题,如下图所示:

展开态

折叠态

因此我们期望应用程序界面在切屏后可以全屏显示,应用程序支持resiszeable 需要在 AndroidManifest.xml 针对Application 或Activity 设置android:resizeableActivity。

<application
  android:resizeableActivity="true"> ->对应用内所有activity 生效
  <activity
      android:resizeableActivity="true" /> ->仅对此activity 生效
</application>

开发者需要根据应用面向的API Level (targetSdkVersion)进行支持resizeable 能力的申明。

•  如果应用程序面向API Level 24 以上(targetSdkVersion>=24),系统将默认应用支持resizeable 能力。

•  如果应用程序面向API Level 24 以下(targetSdkVersion< 24),需要应用在manifest 中显式的声明android:resizeableActivity=true, 才可以支持resizeable 能力。

    备注:虽然安卓提供了申请受限屏幕能力,但强烈建议您为应用设计resizeable 能力,因为一旦您声明了受限屏幕比例(最大或最小)这意味着,当您的app 运行在一个屏幕比例超出了您声明的范围,您的应用程序在屏幕上将出现黑边等现象。

    受限屏幕支持开发者适配指导:https://developer.android.com/guide/practices/screens-distribution?hl=zh-cn

2.2 应用连续性

为了保证应用程序在折叠屏展开/折叠过程无缝切换,开发者需要做应用连续性的设计,以确保应用程序任务不中断。以X Flod 为例,最佳的体验为,应用在展开切换过程中,不发生应用的重启,且切换之前的任务和应用相关状态得以保存和延续。

折叠屏切屏时会触发对smallestscreensize、screensize 和screenlayout 的配置更改。每当发生配置更改时,默认情况下会销毁并重新创建整个activity。开发者可以通过注册监听系统configchanges 消息,不重启应用的情况下处理配置更改,应用程序需要向manifest 中添加android:configchanges 属性,其中至少包含以下值:

android: configChanges = “screenSize|smallestScreenSize|screenLayout” 应用程序需要复

写 onConfigurationChanged() 方法,通过该方法的Configuration 参数获得屏幕的分辨率等信息,就可以针对不同比例屏幕下的应用界面布局做相应调整,如切换布局、调整控件位置和间距等。

public void onConfigurationChanged(Configuration newConfig) {
   super.onConfigurationChanged(newConfig);
if(newConfig.screenWidthDp > xxx) //判定屏幕尺寸
  //load layout
    setContentView(R.layout.activity_main);
    ...
}

如果您的应用必须进行重新走生命周期来以响应屏幕切换,需要进行状态的保存和恢复。

您可以通过OnSaveInstanceState()和ViewModel 对象来进行之前状态保存和后续的恢复。即,在销毁activity 之前,通过onSaveInstancesState()存储状态, 在onCreate() or onRestoreInstanceState()进行状态的恢复。

Note:不要在OnDestroy()中调用finish()或其他自行终止进程。这将导致应用程序在设备折叠或展开时关闭、闪退等问题。

其他适配事项可以参考Android 开发者适配指导(例如链接中提到的 保存界面状态和支持配置变更 部分):

https://developer.android.com/guide/topics/ui/foldables?hl=zhcn#%E5%BA%94%E7%94%A8%E8%BF%9E%E7%BB%AD%E6%80%A7

2.3.判定折叠屏设备方法

根据应用程序判定折叠屏设备的需求,提供了两种判定折叠屏设备的方法。

2.3.1 根据model 机型判定

此方法适用于应用程序已经针对部分折叠屏设备适配且支持新折叠屏设备在线配置生效场景,否则强烈建议开发者通过方法2 判定折叠屏设备。

以X Fold 为例,可以获取如下属性获取model 名

λ adb shell getprop ro.product.model

V2178A

2.3.2 通过接口判定

建议开发者使用此方法判定设备类型,接口说明如下:

类 :android.util.FtDeviceInfo

public static String getDeviceType

返回目前是三种类型:phone、tablet 和foldable

可以通过反射的方式获取设备类型,返回值foldable 表示折叠屏设备。

反射代码示例:

private static boolean isVivoFoldableDevice(){
     try{
       Class<?> c= Class.forName("android.util.FtDeviceInfo");
       Method m = c.getMethod("getDeviceType");
       Object dType = m.invoke(c);
       Log.d("fold","getDeviceType="+dType);
       return "foldable".equals(dType);
     }catch(Exception e){
       e.printStackTrace();
     }
     return false;
}

2.4.调试和验证

2.4.1 通过命令模拟调试

开发者可以在非折叠屏手机上面通过命令修改手机的屏幕分辨率和densityDpi 来进行模拟调试,如下以X Fold 屏幕配置为例模拟切屏(主屏->展开态,副屏->折叠态):

副屏切主屏模拟方法:

(1)预先在手机设置如下屏幕配置:

  adb shell wm size 1080×2520

  adb shell wm density 480

(2)adb shell wm size 1916×2160

主屏切副屏模拟方法:

(1)预先在手机设置如下屏幕配置:

  adb shell wm size 1916×2160

  adb shell wm density 480

(2)adb shell wm size 1080×2520

配置恢复方法:

adb shell wm size reset

adb shell wm density reset

2.4.2 通过模拟器调试

2.4.2.1 Android 折叠屏模拟器

除了通过手机动态切换分辨率的方式来进行调试外,也可以通过模拟器的方式进行调试和验证,Android Studio 模拟器Phone 分类支持8 英寸和7.3 英寸的折叠屏调试,但是无法克隆,即无法修改模拟器的物理尺寸和分辨率,且模拟器System image 如果是x86 的系统,只支持32 位应用的安装和运行,如果是纯64 位的应用,模拟器需要选择arm64-v8a,否则无法安装和运行应用。

Note:

1. Android Studio Foldable 模拟器无法修改物理尺寸、分辨率和densityDpi,因此在适配时,无法完全模拟vivo 折叠屏手机,在app 或activity resizeableActivity = true 时,为了验证切屏是否有黑边可以在Android 原生模拟器查看效果。

展开态
折叠态

2. 64 位模拟器需要PC 主机支持,部分PC 无法正常启动64 位模拟器。

2.4.2.2 折叠屏展开态模拟器

Android 折叠屏模拟器无法修改物理尺寸、分辨率和densityDpi,若应用在进行《2.2 不同分辨率布局适配》时,需要100%模拟折叠屏展开态的屏幕进行调试时,可以通过克隆Tablet分类的Nexus 10,然后修改vivo 折叠屏手机对应的物理尺寸、分辨率和DPI 进行调试和验证。

Note:

1. 应用UI 兼容性适配对物理尺寸有强关联时,请务必修改Screen size 为8.03,分辨率是展开态分辨率

2. 64 位模拟器是否可以运行需要PC 主机支持

3. 若手机模拟densityDpi 和分辨率调试无问题后,无法在模拟器运行,可以发包给vivo 接口人,在vivo 折叠屏真机运行点检。

4. 模拟器无法修改densityDpi,需要启动模拟器后,通过adb shell 命令设置。

此时打开终端,可以看到模拟器设备已经挂载和连接,可以进行adb 操作。

λ adb devices

List of devices attached

emulator-5554 device

模拟器无法直接修改densityDpi,需要启动模拟器后单独设置。

adb shell wm density 480

2.4.3 远程真机调试

目前vivo 已经支持X Fold 远程真机调试,开发者可以访问如下链接使用远程真机

https://vcl.vivo.com.cn/#/machine/picking

远程真机主屏效果图

远程真机副屏效果图

2.4.4 测试用例建议

2.4.4.1 用例1

应用在展开态下页面显示正常

测试步骤:

(1)在屏幕展开的状态下,打开应用,查看应用各个页面显示效果;

预期结果:

(1)应用的所有页面可以全屏显示,页面没有发生截断、拉伸变形、放大模糊,按钮缺失等问题;

2.4.4.2 用例2

应用在展开态下核心页面功能正常

测试步骤:

(1)在屏幕展开的状态下,打开应用;

(2)遍历应用核心页面的控件按钮,所有功能按钮可用,无失效/crash/anr 等问题;

预期结果:

(1)应用在折叠屏展开后,核心页面功能可用

2.4.4.3 用例3

应用在折叠和展开状态切换时业务不中断,应用页面显示和控件点击正常。

测试步骤:

(1)在展开态下,打开应用的测试页面;

(2)在应用的测试页面切换到折叠态,观察页面显示;

(3)点击测试页面的所有控件和按钮;

(4)在折叠态下,打开应用的测试页面;

(5)在应用的测试页面切换到展开态,观察页面显示;

(6)点击测试页面的所有控件和按钮。

预期结果:

(1)应用页面在状态切换过程中,不要出现页面重启、闪退;页面显示正常,不要出

现页面截断、拉伸变形、放大模糊,按钮缺失等问题;

(2)测试页面按钮和控件点击都能正常响应;

(3)应用页面在状态切换过程中,不要出现页面重启、闪退;页面显示正常,不要出

现页面截断、拉伸变形、放大模糊,按钮缺失等问题;

(4)测试页面按钮和控件点击都能正常响应。

三、vivo 多窗模式适配指南

3.1 适配规则

窗口在左右两边拆分显示以Activity 为基本单位,如果要实现拆分,应用窗口需要用Activity 实现和启动,子布局或者非Activity 实现的窗口,无法拆分。以下提供Pad 设备上在横屏时应用不同界面分屏显示的适配方法和规则

3.1.1 AndroidManifest 增加meta-data

在app 的AndroidManifest.xml 文件中 <application>标签内新增

<meta-data android:name=”VivoMultiWindow” android:value=”true” />

3.1.2 Assert 目录新增vivo_multiwindow.json 配置文件

“vivo_multiwindow.json”模板

在 assert 目录下新建配置文件 “vivo_multiwindow.json”,模板示例如下:

{         “funtouchPlugVersion”: “1.1”,       “package”:   “com.vivo.test”,       “elements”:   [                 {                        “fun”: {                                 “name”: “multi-landscape”,                                 “enable”: “true”                        },                        “config”: {                                 “mode”: 1,                                 “action”: [                                         {                                                  “pages”: “com.vivo.test.MainActivity”,                                                  “attachedPage”: “com.vivo.test.primaryActivity1”                                         },                                         {                                                  “from”: “com.vivo.test.FromActivity1”,                                                  “to”: “com.vivo.test.ToActivity”                                         },                                         {                                                “from”:   “com.vivo.test.FromActivity2”,                                                  “to”: “*”                                         }                               ],                               “Activities”:   {                                         “fullscreenActivities”: [                                                  “com.vivo.test.fullScreenActivity1”,                                                  “com.vivo.test.fullScreenActivity2”                                         ],                                         “transitActivities”: [                                                  “com.vivo.test.transitionActivity1”,                                                  “com.vivo.test.transitionActivity2”,                                                  “com.vivo.test.transitionActivity3”                                         ],                               },                               “EX”:   {                                         “draggable”:   “true”,                                         “statusBarVisible”:   “true”,                                         “videoAutoFullscreen”:   “true”,                                         “isRelaunchForResizing”:   “false”,                                         “supportDoubleResume”:   “true”,                                         “windowsGravity”: [                                                {                                                         “deviceType”: “FOLD”,                                                         “gravity”: “1|2”                                                },                                                {                                                         “deviceType”: “PAD”,                                                         “gravity”: “900|1654”                                                }                               ],                               “splitBarColor”:   “0xffe5e5e5”                        }                  }           }      ]}

“vivo_multiwindow.json”字段描述

“vivo_multiwindow.json”具体字段描述如下:

参数描述
funtouchPlugVersion1.0vivo 多窗口功能版本,目前固定1.0
package应用包名
fun.namemultilandscapevivo 多窗口功能名称,固定为multi-landscape
fun.enablefalse/是否启用该配置
false 关闭
true 启用
config.mode0/1默认模式
0 购物模式
1 自定义模式
config.action应用冷启动时默认打开的双界面配置
config.action.pages默认双屏主页面列表
注:可以指定多个,分号隔开,应用冷起动启动该页面,自动在副页面位置启动attachedPage页面
config.action.attachedPage默认双屏副页面
config.action.from(自定义模式生效)触发多窗口的源activity
config.action.to(自定义模式生效)触发多窗口的目标activity
“*”表示任意activity
注:当从源Activity启动目标Activity,自动在主副位置打开对应Activity
config.Activities.fullscreenActivities0/1是否需要全屏启动
0 非全屏
1 全屏
config.Activities.transitActivities过渡页面列表
注:无固定窗口位置,跟随启动时上一级页面窗口位置
config.EX特殊属性配置
config.EX.draggable0/1是否支持窗口拖动
0 不支持
1 支持
config.EX.statusBarVisible0/1是否支持状态栏可见
0 不支持
1 支持
config.EX.videoAutoFullscreen0/1是否支持默认视频全屏播放
0 不支持
1 支持
config.EX.isRelaunchForResizing0/1是否支持重启
0 不支持
1 支持
config.EX.windowsGravity窗口比例
config.EX.windowsGravity.deviceTypeFOLD/PAD设备类型
FOLD 折叠屏
PAD 平板
config.EX.windowsGravity.gravity1|2 /
900|1654
窗口比例
FOLD 默认1|2
PAD 默认900|1654
config.EX.supportDoubleResume0/1是否支持两个界面同时resume
config.EX.splitBarColor分隔条的颜色

3.2 适配建议

3.2.1 状态判断

获取Activity 是否运行在模式下:

String config = context.getResources().getConfiguration().toString();

boolean isInMagicWindow = config.contains(“multi-landscape”);

context 为Activity 的context

配置了Fullscreen 的页面,显示为全屏,但也运行在模式下

3.2.2 获取Activity 显示大小

推荐使用:context.getResources().getDisplayMetrics()

不推荐使用:context.getWindowManager().getDefaultDisplay().getMetrics(outMetrics)

context 为Activity 对应的上下文句柄,每个Activity 应该严格使用自己的context 来进行布局,而不是使用application 的context。

3.2.3 获取Activity 窗口布局方向

获取Activity 窗口方向的方法为:context.getResources().getConfiguration().orientation

当Activity 处于横屏应用显示状态下时,获取的orientation 统一为竖屏;如果Activity是在状态下全屏显示,其orientation 为值为横屏。

获取设备的方向context.getWindowManager().getDefaultDisplay().getRotation()。

3.2.4 指定Activity 全屏显示

横屏应用显示状态下,Activity 希望以全屏展示,有三种方法:

方法一:动态全屏显示,Activity 首先以横屏应用显示非全屏显示,调用Activity 类的如下接口申请横屏方向可进入全屏显示状态:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)

在此状态下,调用Activity 类申请竖屏方向即可退出全屏状态:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)

此场景广泛应用于视频全屏播放场景。

方法二:在配置文件fullscreenActivities 中添加想要全屏的Activity,即可实现Activity默认以全屏启动,此方法中,Activity 会一直以全屏状态显示

方法三:在“AndroidManifest.xml”文件中将Activity 的方向配置为横屏,此方法中,Activity 会一直以全屏状态显示

android:screenOrientation = “landscape”

或android:screenOrientation = “sensorLandscape”

3.2.5 开发建议

•  应用主界面Activity 的启动以singleTask 的模式来启动,保证其在栈内的唯一性。

•  应用内不要存在两个及以上组件名不一样的主界面Activity,例如某个应用在登录前的主界面Activity 组件名与登录后的Activity 组件名不同,会导致新的主界面Activity显示在右半边

•  尽量避免或减少过渡Activity 的使用,尽量避免或者减少使用过渡Activity 来实现Activity 的启动,如果一定要使用,建议使用ActivityA->ActivityB->ActivityC 的启动方式,而不是(ActivityA->ActivityB) + (ActivityA->ActivityC)的方式(示例中,ActivityB 为过渡Activity ) 。过渡Activity 的数量不能超过1 个, 例如ActivityA->ActivityB->ActivityC->ActivityD,其中ActivityB 和ActivityC 是过渡窗口,建议从ActivityA 直接启动ActivityC。

•  Activity 大小切换时不重启适配,建议应用在Activity 窗口大小切换时不重启适配,在android:configChanges 属性增加screenSize|screenLayout|orientation|

smallestScreenSize,并在Activity 的onConfigurationChanged 回调中更新宽高刷新子布局。

•  避免Activity 子布局的缺省重用,由于左右Activity 同时显示,左右显示的两个Activity中不能同时存在单实例的公共布局模块

•  避免左右两个Activity 共用一个播放器,左右两个Activity 同时显示,建议两边使用的播放器资源相互独立,互不影响。

•  建议Camera 相关的Activity 界面配置为全屏显示

3.3 启动返回显示逻辑

基于目前横屏应用显示模式,在模式中启动或者回退链条展示。

3.4 三方适配多窗模式过程中需要注意:

应用更新json 文件后安装不生效,可以通过下面两种方式更新:

1. 修改完之后,升级应用版本号,重新安装应用

2. 把数据库都删除,重新创建,需要root 权限删除数据库之后重启。

adb vivoroot

adb shell rm -rf data/data/com.vivo.smartmultiwindow/*

adb shell rm -rf data/user_de/0/com.vivo.smartmultiwindow/*

建议使用第一种。

vivo折叠屏适配指南1

一、概述

1.1 折叠屏简介

折叠屏手机作为一种具有特殊形态的设备,具备折叠使用的外屏(副屏),和展开使用的内屏(主屏),通常展开使用的内屏尺寸相对较大。

本文主要提供针对折叠屏大屏的适配建议,帮助设计师及开发者能够更简单、快速地将应用适配至折叠屏设备,以确保用户在不同设备中保持应用的一致体验所带来的愉悦感。

1.2 折叠屏形态

    1. 折叠态(副屏):外屏尺寸接近普通直屏手机,其设计规范可与直屏手机基本保持一致。

    2. 展开态(主屏):内屏较外屏有更大的屏幕宽度,需充分利用大屏优势,在信息呈现和交互方式上利用合适的布局方式对应用进行优化调整。

    3. 悬停态:折叠屏设备处于完全展开和折叠的中间状态,可平稳放置。可悬停角度:5°-160°

1.3 折叠屏特性

1.3.1 大屏内容呈现

折叠屏手机的展开态具有以下三个优势:

    1. 展示更多内容:提升信息呈现丰富度与交互效率。

    2. 提升沉浸感:在游戏、电影、视频通话、图片浏览等应用和场景下减少干扰,提升专注度。

    3. 多窗口、多任务:通过展示更多窗口和内容,实现多任务的并行,以丰富体验场景。

1.3.2 主副屏的体验连续

体验连续是指:从一种窗口大小转换为另一种窗口大小时带来无缝的用户体验。无论用户当前置身于什么体验,都应继续进行而不中断,防止用户感知无法接续。

通常情况下,从折叠态切换至展开态时,应用默认在主屏显示运行,并维持在副屏时的应用与任务状态。

同时,用户可在 “设置-显示与亮度-合上屏幕后熄屏” 中选择在展开态切换至折叠态后,是否自动熄屏:

    1. 开启的情况下,折叠设备后,副屏自动熄屏。

    2. 关闭的情况下,折叠设备后,副屏不熄屏并维持在主屏时的应用与任务状态。

二、基础适配原则

2.1 概述

为了避免应用在普通直屏手机移植到折叠屏手机时,缺少针对大屏的优化,导致布局混乱、信息呈现不完整等问题,大幅降低用户体验,建议基于以下三个核心指导建议优化设计:

    1. 适合展开态的界面元素为了发挥折叠屏展开态的大屏优势,在设计时需要基于屏幕特性和业务场景,优化界面布局结构,以提高用户的交互效率与愉悦感。原则上,更大的屏幕应当呈现更多的内容;在页面适配上,应当优先保证所有界面元素显示为适宜的大小,不应将界面单纯的整体放大,导致单屏信息呈现的减少,影响界面的使用效率。

    2. 灵活的响应式布局通过响应式布局建构页面,能够在可用空间发生变化时及时、灵活地进行调整优化。本文提供了多种布局建议,可根据业务场景和具体需求,使用其中一种或多种布局进行最优组合。关于布局的具体介绍,请参考界面布局(2.6)。

    3. 高效利用多窗口交互通过在更大的屏幕上同时展示多个窗口,用户可以高效、直观地处理多个任务,提升使用体验的价值。建议应用为用户在折叠屏展开态中提供更加丰富高效的使用方式,让用户体验得到不同维度的增值。

具体来说,基础适配原则从“信息呈现”与“交互方式”两个维度提供指导建议

2.2 信息呈现

界面中的信息呈现包括图片、视频、卡片、按钮、字体、控件等通用基础体验元素的展示。

屏幕展开前后,通用基础体验元素需保持一致。如:元素不发生变形、裁剪、信息显示不全或者模糊等情况,避免信息呈现的不一致。

2.3 基础元素适配

需将所有界面元素显示为适宜的大小。不应过大或过小,影响显示效率。

不应从折叠态到展开态直接等比放大文字图标、图片视频等要素,图片与文章的比例与在直屏手机的界面设计出入过大,导致用户在大屏界面中与在直屏手机中的感知不符合预期。

2.4 弹出框适配

建议应用在展开态下的弹出框尺寸与折叠态下弹出框尺寸保持一致,如因特殊需求,需要进行放大,则不应超过原尺寸的1.3倍

2.5 交互方式

2.5.1 合适的交互区

在展开态时,由于用户双手握持设备的情况较为常见,手指会难以顺利在屏幕所有区域进行交互。为了确保户的交互体验的高效与愉悦,在设计展开态布局时,应考虑到以下三个交互区域:

        ① 用户易于触达的区域。操作频率最高的控件元素建议放在此区域。

        ② 用户可以触达的区域。但有时候可能会造成一定不便,有一定操作频率的控件元素建议放在此区域。

        ③ 用户较难触达的区域。除特殊情况,不建议将需要交互的控件元素放在此区域。

2.3.2 折叠屏手机形态

折叠屏手机形态分为折叠态、展开态与悬停态:

    1. 折叠态:折叠屏手机折叠后的形态,折叠后屏幕尺寸变小。

    2. 展开态:折叠屏手机展开后的形态,展开后屏幕尺寸变大。

    3. 悬停态:折叠屏设备处于完全展开和折叠的中间状态,可平稳放置。可悬停角度为:5°-160°

在悬停状态下,建议“上半屏显示内容,下半屏展示操作”。

例如在视频播放的悬停态中,上半屏为播放页,下半屏为操作区,更方便地进行拖动播放进度、暂停、调节亮度音量等操作。

2.6 界面布局

由于折叠屏在展开态下,屏幕尺寸和比例与直屏手机差异较大,需根据不同需求调整合适的布局,确保用户在不同形态上保持一致的体验。

界面布局主要分为“相对拉伸”、“相对缩放”、“挪移”、“延伸”、“分栏布局”5个类别。

相对拉伸

布局中元素的高度为固定值,元素的宽度对比参照物确定,元素的显示宽度或者元素之间的间距随着屏幕变大而相对变大。

相对拉伸适用于文字内容、输入框、搜索框等。需要注意的是,随着拉伸而改变比例的图片是一种延展,不应因拉伸而变形。

相对缩放

布局中元素的大小比例保持固定,通过对比参照物确定尺寸,显示宽度随着屏幕变大而放大。

相对缩放适用于全屏状态下有固定比例的元素,如图片、视频等。页面中的图片比例不建议放太大,应保持合适的比例。

挪移

当屏幕宽度发生变化时,部分模块的布局可以挪动位置,例如将原先的上下布局切换成左右布局,用以提供屏幕的利用率。

挪移适用于信息层级相对较少的页面,例如歌单详情页等。

延伸

布局中元素横向布局,元素间的距离固定,可显示元素的数量随着显示宽度的改变而变化。

延伸布局适用于资讯TAB、内容推荐卡片、可视化数据等。

瀑布为延伸的拓展用法,将原来单列纵向布局,切分为两列或多列的纵向布局,在⼤屏上呈现更多内容。

分栏布局

具有 “父子和父父关系层级”的列表应用,可以左侧展示一级页面右侧展示其优先级高的子页面。

分栏布局适用于 IM、笔记、信息、邮件等列表类应用。

2.7 多窗口交互

多窗口类别优势适用场景
悬浮小窗通过减少跳转,更快处理临时任务,且广泛适用于各种场景多应用多任务单应用多任务
分屏双应用/任务的并行处理,且广泛适用于各种场景多应用多任务单应用多任务
应用多窗以多实例实现应用内的双窗口单应用多任务

悬浮小窗

悬浮小窗以小窗的形式展现应用,并支持不同窗口形式(小窗、分屏、全屏)之间快速切换。

小窗入口包括但不限于:近期任务卡片“小窗”选项,应用内滑、悬浮通知下拉等。

悬浮小窗能通过减少跳转,更快处理临时任务,且广泛适用于各种场景。

悬浮小窗技术接入规范:https://dev.vivo.com.cn/documentCenter/doc/582

分屏

vivo分屏在原生分屏的基础上做了定制化处理,例如增加分屏方式(消息三指组合)、分屏小桌面列表、输入法边界定制、加密界面定制等。

分屏的优势在于多应用/任务的并行处理,且广泛适用于各种场景。

vivo分屏的手势分屏方式为:三指上滑

分屏技术接入规范:https://dev.vivo.com.cn/documentCenter/doc/573

应用多窗

应用多窗以多实例实现应用内的双窗口,根据应用自身特性进行界面组合,减少频繁切换窗口的行为,提升效率。

应用多窗的优势主要分为以下两个:

    1. 同时比较两个同类型内容的不同信息。比如两个不同的图像、文档、商品详情等。

    2. 同时显示多级页面,呈现相同信息的不同维度。通常为主次关系,比如左半屏展示列表页面,右半屏为选中项的详情页面。适用于电商购物、通讯社交、效率办公等频繁切换窗口的应用场景。

应用多窗-左静右变

应用多窗提供了“左静右变”和“左变右变”两种交互规则:

左静右变的规则为:左侧固定页面,右侧可变,进行内容切换,右侧窗口是最终窗口。

适用于效率办公和通讯社交类应用。

应用多窗-左变右变

左变右变的规则为:左侧右侧皆可变。在右侧交互后启动新窗口时,把右侧界面往左推,新的界面在右侧展示。

适用于购物场景类应用。

跨应用拖拽

跨应用拖拽可以让用户将一个应用中的图像、文档或文件拖拽到另一个应用中。

通过分屏和悬浮小窗实现在大屏的跨应用拖拽,减少用户在应用之间来回切换,更高效地进行多任务处理,提高生产力。

关于跨应用拖拽的适配:https://developer.android.com/guide/topics/ui/drag-drop

三、典型场景

3.1 影音娱乐

影音娱乐类场景以大量影音内容资源带来的沉浸式体验为主。

3.1.1 视频资源平台

首页推荐

视频列表页

3.1.2 短视频/直播互动页

3.1.3 音乐播放界面

3.1.4 视频播放界面(悬停)

3.2 资讯阅读

资讯阅读类场景以信息的聚合为主,需利用屏幕优势,确保用户对关键信息浏览、理解的完整和高效。

3.2.1 首页布局:左右图文结构

3.2.2 首页布局:上下图文结构

3.2.3 资讯详情页

3.3 生活服务

生活服务类场景广泛地包含了购物、饮食、出行、学习等用户日常生活的各个方面。

3.3.1 首页列表

3.3.2 详情页面

3.4 通讯社交

社交通讯类场景主要包括:文字交流为主的IM对话、图像视频通话、社交动态等场景。

3.4.1 文字交流为主(IM对话)

3.4.2 图像·视频通话

3.4.3 社交动态

首页结构:推荐

详情页

可根据实际情况,自由选择应用多窗的两种交互规则。请参考基础适配原则-交互方式-多窗口交互(2.7)

3.5 效率办公

效率办公类场景以高效的体验,辅助和提升工作者的办公效率为主。

3.6 H5页面

H5页面以其便利的特性,广泛应用于小程序和网页版应用。

3.7 金融理财

用户在金融理财类场景中,需确保大屏信息呈现所带来的高效与舒适。

同时,需保障用户办理金融业务过程中的易用性。

3.7.1 首页布局

3.7.2 股票·走势详情页

3.8 游戏

根据不同的游戏类型和场景,优化大屏布局,在呈现与交互层面给用户带来愉悦的体验。

同时,考虑到用户在玩游戏时长时间握持设备,在设计展开态布局时,应根据不同的交互区做适配优化。

请参考交互方式(2.5)-合适的交互区

四、测试应用

4.1 设备尺寸

可在 Android Studio 中基于以下设备规格信息进行测试。

屏幕类型对角线长度(英寸)比例分辨率(像素)
主屏(展开态)8.034:3.551916*2160
副屏(折叠态)6.5321:9 1080*2520