关于前端:可折叠Web可能会给我们带来的变化

41次阅读

共计 11869 个字符,预计需要花费 30 分钟才能阅读完成。

简介: 可折叠 Web 行将到来,咱们应该去思考可折叠 Web 可能会给咱们带来什么变动,如果这一天真的到来,咱们的技术是否反对该设施?

作者 | 大漠


可折叠 Web 的说法是可折叠设施带来的。可折叠设施形式多样,从笔记本电脑到手机,再到离奇的双屏幕混合设施。对于这类新发明并没有一个全面的定义,但大多数都能够归为两类。“可折叠”是指屏幕能够折叠的设施(比方华为 Mate X,三星 Galaxy Z Flip);而“双屏”设施的屏幕是离开的,但也能够以独特的形式一起工作,以灵便的模式提供生产力(比方,微软的 Surface Neo 和 Surface Duo)。当波及到 Web 设计时,这两种类型可能会遵循相似的规定。如果这项技术能大获胜利,那么 Web 设计将面临十年来最大的改革。这对于咱们 Web 开发者而言,也将会开启新的旅程。

听起来就很令人兴奋,但这到底意味着什么呢?可折叠 Web 将带来新的挑战,新的时机,而且很可能还会带来新的概念。互联网可能也会经验自智能手机以来最大的改革。你可能会认为这是一种炒作,但事实上这样的一天曾经离咱们不是太远。记得在去年这个时候,有些挪动品牌商,比方华为,三星都推出可折叠的硬件设施,而微软,苹果等公司在幕后的致力也不逊色。能够说可折叠 Web 行将到来。咱们真的应该去思考可折叠 Web 可能会给我带来什么变动?如果这一天真的到来,咱们的技术是否能反对该设施。简略地说,咱们开发的 Web 页面能不能在可折叠设施和双屏幕上完满的运行。

可折叠和双屏设施

可折叠设施采纳的是一种柔性屏幕技术,该技术的钻研始于 20 世纪 70 年代,但直到世纪之交才失去真正的倒退。特地是在去年,失去了爆发式的倒退——在市场上能看到一些可折叠设施终端。比方三星 Galaxy Z Flip 手机,模拟的是老式的翻盖手机:

比方三星的 Galaxy Fold 手机,在折叠状态是一个小屏幕,开展状态是一个宽屏幕:

比方华为 Mate X,屏幕是包裹在手机里面的:
.gif”)
还有很多像电子书一样,当设施齐全关上时,外部的两个显示屏会合二为一。通常在里面有一个独立的小屏幕,这样用户在应用的时候就不必关上它。

双屏幕设施是具备两个对称屏幕的便携式设施,以独特的形式一起工作,以灵便的模式提供生产力。比方像微软的 Surface Neo 和 Surface Duo 这样的双屏幕设施,人们能够比以往任何工夫都更快地实现工作。如果你应用过 Surface Neo 这样的双屏幕设施,你能够在一个屏幕上做笔记,在传输过程中在另一个屏幕上查看残缺的我的项目建议书:

只管当初市场上有不同的折叠屏,双屏幕设施,而且还会有更多的相似设施呈现,但咱们置信为这些设备设计应用程序会有一个独特的办法。咱们心愿这将帮忙你的应用程序能跑在更多的设施上,而不须要为不同的设施做非凡的设计和解决。

换句话说,在可折叠屏或双屏幕的设施上,用户能够做更多的事件,比如说让屏幕分屏,能够同时关上多个应用程序:

也能够关上同一个利用,在利用中分屏,关上不同的页面,比方:
.gif”)
像上图这样,应用程序在两个屏幕上显示,就是所谓的跨屏布局。默认状况下,该应用程序将体现得如同它是在一个更大的屏幕上显示。你也能够扭转你现有的应用程序布局来适应两个屏幕之间的缝隙,或者你能够更进一步,允分的利用双屏幕设施而专门创立不同的布局控件。比方 iPad 版本的手淘,就能够分屏展现:

新的 Web 规范、新的体验和新的问题

可折叠和双屏幕设施正在呈现。这曾经不是概念,也不是炒作。这更不是重点。重点是:

可折叠和双屏幕这项技术将如何影响 Web 开发人员、用户体验设计师以及其余以提供高质量浏览体验为业务的人。

首先可折叠和双屏幕会给视觉设计师在做设计的时候带来很大的变动。

整个可折叠的概念是基于你能够把你的手机变成平板电脑的想法。市场上大多数平板电脑的屏幕宽高比都是 4:3,所以手机和平板电脑的混合也应该是 4:3。这应用折叠设施达到 3:2。而这些比率都不能保障 16:9 或 18:9 的实在视频体验。其中 4:3 的宽高比更适宜在各种文本和图形编辑器中执行工作和工作,比方 iPad,但它须要更大的分辨率,这是可折叠设施无奈做到的。这使得大多数可折叠手机处于一个含糊地带,给人用户的体验就会变得很蹩脚,这也是因为在传统手机中是无奈达到 16:9 的比例。

为了让可折叠手机成为一种有用的媒体设施,它必须转换成 16:9 或 18:9 的设施,而后再折叠成 8:9 或 9:9 —— 基本上就是一个正方形。@Nathan Cunn 通过计算得出结论,折叠手机的完满宽高比应该是其宽度的 1.4 倍。

这也将会是 iPhone 折叠屏将会采纳的一种宽高比例:

除此之外,不论是可折叠设施还是双屏幕设施,最大的特色就是屏幕变大了,在开展的状态下和平板一样了。这样一来,可用的空间就变大了。

可折叠和多屏设施突破了挪动设施(手机)可用空间小的解放!

空间大了,能搁置的内容就多了,如果设计还是按着以前的思路,间接拉伸平满全屏,就过于节约了。面对这样的场景,除了响应式 Web 设计能帮忙咱们更好的利用可用空间之外,还能够参照淘宝设计提出的一个概念:

让你的内容像水一样的流动(“Content is like water”)

用一张图来形容:

有对于这方面更具体的介绍,能够关注淘宝设计微信公众号。

你能够搜寻“可折叠”关键词,能找到一些这方面的文章,比方:

  • 不要诧异,折叠屏就应该这样设计!
  • 独家揭秘淘宝折叠屏设计底细与适配开发
  • 跨端设计又双叒来了,只是响应式换个名字?

对于双屏幕给设计带来的变动,或者说设计应该要留神的细节,能够浏览微软官网有对于双屏幕的介绍:《Introduction to dual-screen devices》。

另外,折叠屏幕还会带来一些其余的设计和体验变动。

单(双)手挪动设计

随着状态的扭转(这里的状态是折叠和开展状态,单屏和多屏状态),整个体验自身也随之扭转。目前大多数用户都习惯用一只手操作挪动设施(手机),而开展状态,就像 iPad 了,这个时候须要两只手来操作设施(或利用)。

手机操作 vs 平板操作

屏幕连续性和距离

可折叠设施和多屏幕设施有着显著的区别。

可折叠设施在开展状态时,它的屏幕是连续性的,咱们在设计的体验应该无缝地转移到全屏上。
.gif”)
针对这样的情景,如果只是粗犷的放大到全屏,那么布局上不会有太多的变动,只不过对于 Web 中的局部对象会变得含糊,比方图像。当然,也能够思考设计上做差异性的解决,比如说做分屏设计:
.gif”)
对于多屏幕设施,有可能屏幕不是连续性的,比方微软的 Surface Neo 和 Surface Duo,屏幕之间就有一个间隙:

在设计和布局的时候,就须要防止 Web 对象处在两个屏幕的间隙之间,比方:

或者:

多窗口,多利用

后面提到过,折叠屏和多屏幕最大的特色之一,就让咱们有更多的空间可利用。这样对于用户来说,对于解决多任务更敌对,能同时做更多的事件。因而,咱们应该始终思考用户可能会同时运行多个 App 利用。比如说,一边查看日历,一边查看地图,一边看新闻:

除了同时关上多个 App 利用之外,还能够在同一个 App 中,分屏做不同的事件,比方,一边看直播,一边逛淘宝:
.gif”)
折叠屏和多屏幕除了给设计师带来新的挑战之外,给 Web 开发者也带来相应的挑战。在去年华为 Mate X 进去的时候,有幸参加在 Mate X 做一些 Web 端的适配解决。次要解决 H5 的利用完满适配折叠屏设施。

因为相干 H5 业务采纳的都是视窗单位 vw(我常称该计划为 vw-layout),能较好的让相应的 H5 业务适配折叠屏开展状态,但也存在一些相应的问题,最为突出的是图像变得含糊:

当然也尝试着采纳响应式 Web 设计来做不同的布局解决:

尽管该形式能够让咱们的 H5 利用最大化的利用折叠屏可用空间,但也存在肯定的缺点。因而在《聊聊安卓折叠屏给交互设计和开发带来的变动》一文中提出相应的概念:

解决折叠屏时,咱们应该像一些带有刘海设施(比方 iPhone X)一样,具备独特的检测个性来检测折叠设施或多屏幕设施。

值得庆幸的是这一年来,在这方面有了显著的变动,尤其是微软公司的团队对可折叠技术的探索和探讨十分的踊跃。在往年 2 月份,三位微软开发人员 @Bogdan Brinza、@Daniel Libby 和 @Zouhir Chahoud 发表了一篇文章,解释如何应用 JavaScript API 和 CSS 媒体查问来解决可折叠和多屏幕设施的布局。

该文档提出两个概念:用于双屏幕布局的 CSS 和 窗口段枚举的 JavaScript API。它的主旨是作为探讨折叠屏和多屏幕在 Web 开发中技术标准。即:以可折叠和双屏幕设施为指标的 Web 开发人员可能在跨多个显示区域的窗口中无效的对 Web 利用进行布局。

将来解决可折叠或多屏幕的 Web 技术

从 @Bogdan Brinza、@Daniel Libby 和 @Zouhir Chahoud 三位开发者在 Github 上发表的文档《Web Platform Primitives for Enlightened Experiences on Foldable Devices》来看。解决可折叠和多屏幕设施的 Web 布局次要由两局部个性组成,其一是 CSS 的媒体查问个性,其二是 JavaScript API。

接下来,咱们次要围绕着这两个局部来开展。

用于构建双屏幕布局的 CSS 个性

特地申明:用于双屏幕布局的 CSS 还处于 W3C 标准的草案当中,所有皆有可能会变。

@Brinza、@Libby 和 @Chahoud 提出了一个 CSS 个性,即媒体个性,它能够确定网站是否逾越两个相邻的显示区域,以及这两个相邻显示区域的配置。相应的还提出了另一个个性,即环境变量(指的是用户代理定义的环境变量),它将帮忙 Web 开发人员以 CSS 像素计算每个屏幕区域的大小。

为什么要提出新的 CSS 个性

当浏览器窗口逾越设施折叠时,通知 Web 开发者折叠方向和显示边界能够帮忙他们开发进去具备较好体验的 Web 利用。这里疾速概述可能会呈现的模式。

将更大屏幕的 UI 模式带到更小的便携设施

因为屏幕尺寸的限度,传统的便携式触摸设施在很大水平上依赖于“叠加视图”,比方点击收件箱列表中的一封邮件,就会导致整个收件箱列表视图被选中的邮件内容视图所取代。这种行为通常会创立额定的操作步骤;而在更大屏幕的设施上将会有一个更天然的配置,邮件收件箱列表视图和邮件内容视图是并排的。

当然,这种从新发明的模式并不是惟一的解决方案,只不过可折叠屏和多屏幕设施绝对于传统的便携触摸式挪动设施来说多了一个显示器,相当于减少一个屏幕空间,这样一来能够为 Web 开发者和设计师提供独特的机会来发明新的体验。

轻松改良现有的 Web 利用和 UI 组件

Web 开发人员可能不想为这类设施引入次要的 UI 更改,而只想简略地挪动一些组件。在上面的示例中,对于模态对话框(Modal)防止设施折叠更有意义(无论可折叠设施是无缝的还是有间隙的),并容许 Web 开发人员逐渐加强他们的站点,提供更好的体验。

也正因为这些起因,提出了相应的 CSS 个性和设计准则。

CSS 媒体个性:spanning

提出一个新的媒体个性:spanning,该个性可用于检测浏览器窗口是否逾越多个显示区域。

spanning 个性次要有三个值:

  • single-fold-vertical:屏幕是程度的,布局视图逾越单个折叠(两个屏幕)并且折叠姿态是垂直时(分左右两边),这个值是匹配的
  • single-fold-horizontal:屏幕是垂直的,布局视图逾越单个折叠(两个屏幕)并且折叠姿态是程度时(分高低),这个值是匹配的
  • none:形容浏览器窗口不处于逾越模式时的状态

辨认折叠或多屏设施的 CSS 环境变量

这个有点相似于刘海设施一样,通过 env()函数来辨认环境变量,即辨认平安区域:

  • env(safe-area-inset-top):在 Viewport 顶部的平安区域内设置量(CSS 像素)
  • env(safe-area-inset-bottom):在 Viewport 底部的平安区域内设置量(CSS 像素)
  • env(safe-area-inset-left):在 Viewport 右边的平安区域内设置量(CSS 像素)
  • env(safe-area-inset-right):在 Viewport 左边的平安区域内设置量(CSS 像素)


这份倡议预约义了几个可辨认折叠或多屏设施的 CSS 环境变量:fold-top、fold-left、fold-width 和 fold-height。

Web 开发人员能够利用这些变量来计算横屏和竖屏的每个屏幕片段大小。

留神,这些 CSS 环境变量的值是 CSS 像素,并且是绝对于布局视图的(即在客户端坐标中,由 CSSOM 视图定义)。当不处于逾越状态时,这些值将被视为不存在,则会取 env()函数的回退值。

来看一个简略的示例:一个地图应用程序,在一个屏幕上显示地图,在另一个屏幕上显示搜寻后果。如下图所示:

如果用 CSS 代码来实现的话,大抵如下:


@media (spanning: single-fold-vertical) {   
    body {flex-direction: row;}

    .map {flex: 1 1 env(fold-left)
    }

    .locations-list {flex: 1;}
}

spanning 的 Polyfill

到目前为止,新增的 CSS 媒体个性 spanning 和相应的环境变量都还处于草案的探讨阶,但如果你要尝试着在折叠设施或多屏幕设施上应用该个性的话,能够应用 @darktears 提供的一个 Polyfill。

这个 Polyfill 的应用很简略,你能够应用 NPM 将这个 Polyfill 加载到你的我的项目中:

npm install --save spanning-css-polyfill

装置完之后,通过 <script> 将对应的 spanning-css-polyfill.js 引入到我的项目中:

<script type="module" src="/path/to/modules/spanning-css-polyfill.js"></script>

也能够应用 import 的形式引入:

import "/path/to/modules/spanning-css-polyfill/spanning-css-polyfill.js";

这样你就能够在 CSS 中应用 spanning 这个新媒体查问个性和 CSS 环境变量 fold-top、fold-left、fold-width 和 fold-height。

当然,你还能够手动扭转显示(display)相干的配置。比方,通过导入 FoldablesFeature 对象:

import {FoldablesFeature} from '/path/to/modules/spanning-css-polyfill/spanning-css-polyfill.js';

能够通过 FoldablesFeature 对象来更新像 spanning、foldSize 和 browserShellSize 等值。你也能够订阅 change 事件,以便 spanning 媒体查问个性或环境变量产生变更时失去相应的告诉。

import {FoldablesFeature} from '/path/to/modules/spanning-css-polyfill/spanning-css-polyfill.js';

const foldablesFeat = new FoldablesFeature;

// Add an event listener.
foldablesFeat.onchange = () => console.log("change");

// Add as many event listeners as you want.
foldablesFeat.addEventListener('change', () => console.log("change"));

// Change a single value; results in one update (one 'change' event firing).
foldablesFeat.foldSize = 20;

// Change multiple values by assignment; results in one update.
Object.assign(foldablesFeat, { foldSize: 50, spanning: "none"});

// Change multiple values in one scope; results in one update
(function() {foldablesFeat.foldSize = 100; foldablesFeat = "single-fold-horizontal"})();

有对于 spanning 更具体的应用,能够查看 Github 上的相干教程。

枚举窗口片段的 JavaScript API

特地申明,枚举窗口片段的 JavaScript API 已移到 W3C 第二屏幕社区组。相干的解释、问题和评论,能够参阅 GitHub 的 webscreens/window-segments 仓库。

这里提出了一个窗口片段的新概念,它示意位于独自(相邻)显示上的窗口区域(及其尺寸)。窗口片段尺寸以 CSS 像素示意,并容许 Web 开发者通过 JavaScript API 对窗口片段进行枚举,在相应的窗口片段上搁置独立内容。

这个倡议次要针对响应式场景,在这种状况下,Web 应用程序心愿利用逾越多个显示的劣势,通过用户、窗口管理器将其置于该状态。它不适宜将内容事后搁置在各种可用显示的独自顶级浏览器上下文的状况(这属于 Window Placement API 和 Presentation API)。请留神,应用枚举窗口片段的 API 和 Web 现有的个性,能够应用 JavaScript 来编写穿插显示和窗口的矩形,同时思考 devicePixelRatio 来,计算横跨多个显示的窗口区域。不过,这个并不能正确的解决将来设施模式中存在的极其状况,因而,这个提议试图解决 Web 开发人员针对或思考显示内容屏幕作为一个理论的终点。

简略地来说,Web 开发者能够应用 getWindowSegments()来获取一个 DOMRects 数组,而后依据每个窗口片段返回的数据,开发人员可能推断出可用链接(Hinge)的数量以及其方向。

用户能够在任何时候将浏览器窗口脱离逾越模式,并将其放在某个屏幕上,反之亦然,在这种状况下,将触发窗口 resize 事件,从而能够查问并取得可用屏幕段的数量。

比方咱们下面提到的示例:

如果应用 JavaScript 来解决的话,能够像上面这样:

const screenSegments = window.getWindowSegments();

if(screenSegments.length > 1) {
    // 当初咱们晓得这个设施是可折叠(可多屏幕)的
    // 倡议测试 screenSegments[0].width === screenSegments[1].width 
    // 能够更新 CSS 类,实现不同的布局成果

    document.body.classList.add('is-foldable');
    document.querySelector('.map').classList.add('flex-one-half');
    document.querySelector('.locations-list').classList.add('flex-one-half');
}

咱们再来看另一个示例,当窗口的 resize 事件和 spanning 状态发现变动时解决计划。

先看 CSS 的解决方案:

@media (spanning: none) and (max-width: 728px) {    
    body {flex-direction: column;}

    .map {flex: 0 0 300px;}

    .locations-list {flex: 1;}
}

如果应用 JavaScript 能够这样:

window.onresize = function() {const segments = window.getWindowSegments();
    console.log(segments.length) // 1

    if(screenSegments.length > 1) {document.body.classList.add('is-foldable');
        document.querySelector('.map').classList.add('flex-one-half');
        document.querySelector('.locations-list').classList.add('flex-one-half');
    }
}

实战:多屏幕布局

最初咱们来看理论案例。

你可能在手上没有折叠屏或多屏幕的设施,有可能无奈看到实际效果。但能够应用一款基于 Web 的模拟器,这款模拟器能够模仿微软 Surface Duo 和 Surface Neo 两款分屏设施:

embed: foldable-web-27.mp4

@kenchris 在 GitHub 上 spanning-css-polyfill 提供了几个 Demo,咱们来看最简略的 basic 中的 index.html。

HTMl 局部很简略(这个 Demo 自身就很简略):

<div class="wrapper">
    <div class="col1"></div>
    <div class="col2"></div>
</div>

</body> 前加载了一个.js 文件,依据 CSS Spanning Polyfill 提供的一些办法,解决一些全局款式,甚至能够依据 JavaScript 的 API 来构建 CSS 方面的款式。

<script type="module" src="../../src/index.js"></script>

index.js 对应的具体代码能够点击这里查阅。

接着看 CSS 局部。在 CSS 中应用媒体查问个性:


/* 一般设施下对应的 CSS */
.wrapper {
    display: flex;
    height: 100%;
    width: 100%;
}

.col1 {
    flex: 0 0 200px;
    background-color: lightgray;
    transition: background-color .2s linear;
}

.col2 {
    flex: 1;
    background-color: papayawhip;
    transition: background-color .2s linear;
}

.col1:before {content: "not spanning";}

.col2:before {content: "not spanning";}

不是分屏(或折叠)设施中,看到的成果像上面这样:

在程度方向分屏状态(即 spanning 取值为 single-fold-vertical)下的 CSS:


@media (spanning: single-fold-vertical) {
    .col1 {flex: 0 0 env(fold-left);
        margin-right: env(fold-width);
        background-color: steelblue;
    }

    .col2 {background-color: yellow;}

    .col1:before {content: "spanning single-fold-vertical";}
    .col2:before {content: "spanning single-fold-vertical";}
}

留神,示例中还应用了 CSS 的 env()函数,调用了 CSS 环境变量 fold-left 和 fold-width。这个时候看到的成果如下:

当你把浏览器模式(Browser Mode)切换为“Left”或“Right”时,看到的成果如下:

上图是 Surface Duo 模拟器,Browser Mode 为 Left 状态成果

上图是 Surface Duo 模拟器,Browser Mode 为 Right 状态成果

接下来再来设施垂直方向分屏(即 spanning 取值为 single-fold-horizontal)的布局款式:


@media (spanning: single-fold-horizontal) {
    .wrapper {flex-direction: column;}

    .col1 {flex: 0 0 env(fold-top);
        margin-bottom: env(fold-height);
        background-color: pink;
    }

    .col2 {background-color: seagreen;}

    .col1:before {content: "spanning single-fold-horizontal";}
    .col2:before {content: "spanning single-fold-horizontal";}
}


同样的,如果你把模拟器的浏览器模式切换到 ”Top” 或 ”Bottom” 状态下,看到的成果也会不一样:

最初,你还能够在 spanning:none 状态下设置相应的 CSS:

@media (spanning: none) {
    .col1:before {content: "spanning:none";}
    .col2:before {content: "spanning:none";}
}

下面是一个较为简单的示例。那么接下来,咱们在下面的根底上把页面做得略微简单一点:

<!-- HTML -->
<ul class="card__container">
    <li class="card">
        <div class="card__object"><img src="//source.unsplash.com/300x300?01" alt="Psychopomp"></div>
        <div class="card__body">
            <h4 class="card__title">Psychopomp</h4>
            <p>Japanese Breakfast</p>
        </div>
    </li>
    <!-- ... -->
</ul>

依照下面的示例,在媒体个性之外,给一般设施增加款式(也能够说是全局款式):


/* 布局要害款式 */
body {
    width: 100vw;
    min-height: 100vh;
    margin: 0;
    padding: 2vh;
}

.card__container {
    gap: 2vmin;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    grid-auto-flow: dense;
}

.card:nth-child(1) {grid-column: span 2;}

.card:nth-child(6) {grid-column: span 3;}

一般设施(非折叠和分屏)下成果点击这里查看。

拖动浏览器时扭转视窗大小,看到的成果如下:
.gif”)
在不对 spanning 媒体个性下做任何款式解决时,在分屏状态下看到的成果如下:

同样的,先对 spanning: single-fold-vertical 做款式上的解决:

@media (spanning: single-fold-vertical) {

    .card__container {gap: env(fold-width);
        grid-template-columns: repeat(auto-fit, minmax(calc((env(fold-left) - env(fold-width) - 4vh) / 2), 1fr));
    }

    .card:nth-child(6) {grid-column: span 2;}
}

这个时候程度分屏状态下的成果如下:
.gif”)
接着来看垂直方向的分屏状态下的成果,先来看未解决时的成果:

接下来在 spanning: single-fold-horizontal 媒体个性下做一些布局上的解决:

@media (spanning: single-fold-horizontal) {

    .card__container {
        gap: 20px;
        grid-template-columns: 1fr;
        grid-template-rows: calc(env(fold-height) - 4vh);
    }

    .card__object {height: 250px;}

    .card:nth-child(1) {grid-column: span 1;}

    .card:nth-child(6) {grid-column: span 1;}
}

看到的成果如下:
.gif”)
实际操作的时候,应该依据本人的应用场景,而后对应的媒体查问个性中配合 CSS 本地环境应用,实现不同的成果。

有对于这方面的 Demo,还能够查阅:

  • CSS Spanning media feature polyfill & example
  • Window Segments Enumeration API polyfill & example

小结

可折叠 Web 的呈现,让挪动优先的设计变得更加简单,但也更加令人兴奋。可折叠 Web 可能是第一次手持设施感到空间的扩大而不是限度。对于一些 Web 利用或 Web 页面来说,须要做肯定的调整,而对于另一些 Web 利用来说,则意味着须要大规模的从新设计。这个范畴取决于开发人员的翻新。

参考资料

  • Web Platform Primitives for Enlightened Experiences on Foldable Devices
  • Window Segments Enumeration API
  • CSS Foldable Display polyfill
  • 分屏模拟器

正文完
 0