京東小程式摺疊屏適配探索

来源:https://www.cnblogs.com/Jcloud/archive/2023/05/08/17380838.html
-Advertisement-
Play Games

京東小程式近年來支持了越來越多的業務和應用,做好小程式的摺疊屏的適配也是符合未來的發展趨勢,能為用戶和業務方提供更好的體驗和價值。 ...


前言

隨著近年來手機行業的飛速發展,手機從功能機進入到智能機,手機屏幕占比也隨著技術和系統的進步越來越大,特別是Android 10推出以後,摺疊屏逐漸成為Android手機發展的趨勢。

圖 1 Android手機屏幕發展趨勢

京東小程式近年來也支持了越來越多的業務和應用,做好小程式的摺疊屏的適配也是符合未來的發展趨勢,能為用戶和業務方提供更好的體驗和價值。

Android應用摺疊屏適配摘要

應用在摺疊屏運行時,可以從一個屏幕切換到另一個屏幕。應用應該做好配置變更的適配和界面狀態的保存,以保證應用當前任務能無縫遷移到轉換後的屏幕,從而為用戶提供出色的連續性體驗。

1.resizeableActivity

預設情況下,Activity resizableActivity 屬性為 true,系統假定該應用完全支持多視窗並且可調整大小。

圖 2 Android手機摺疊屏

如果您不希望自己的應用在多視窗模式下調整大小,你可以設置Activity resizableActivity 屬性為false,系統會將應用置於相容模式。某些原始設備製造商 (OEM) 可能會實施一項功能,即每當 Activity 的顯示區域發生更改時,都會在屏幕上添加一個小型重啟圖標。這為用戶提供了在新配置中重啟 Activity 的機會。下圖示例展示了一次內屏到外屏,外屏到內屏切換中系統相關處理。

圖 3 摺疊屏應用重啟示例

此外,用戶需要“設置”-“顯示”中打開應用的“在外屏上繼續使用應用程式”開關,否則,切換到外屏時系統將回到鎖屏界面,應用會被壓至後臺。不支持resize的應用會無法打開此開關。

圖 4 Android摺疊屏展示開關

2.屏幕寬高比

Android 10 (API 級別 29) 或更高版本 支持更多種寬高比。對於可摺疊設備而言,設備類型可以是超長、超薄的屏幕(例如屏幕寬高比為 21:9 的摺疊設備),也可以是 1:1 的屏幕。

如要與儘可能多的設備相容,您應該儘量多針對以下屏幕寬高比測試自己的應用:

圖 5 Android手機屏幕寬高比

如果無法支持上述某些高寬比,您可以使用 maxAspectRatio(同之前一樣)以及 minAspectRatio 來指明自己應用可以處理的最高寬高比和最低寬高比。如果屏幕寬高比超出這些限制,應用可能會進入相容模式。

3.處理配置變更

某些設備配置可能會在運行時發生變化(例如屏幕方向、鍵盤可用性,以及當用戶啟用多視窗模式時)。發生這種變化時,Android 會重啟正在運行的 Activity(先後調用 onDestroy() 和 onCreate())。重啟行為旨在通過利用與新設備配置相匹配的備用資源來自動重新載入您的應用,從而幫助它適應新配置。

如要妥善處理重啟行為,Activity 必須恢復其先前的狀態。您可以同時使用 onSaveInstanceState()、ViewModel 對象以及持久存儲,以在配置變更時保存並恢復 Activity 的界面狀態。

然而,您可能會遇到這種情況:重啟應用並恢復大量數據不僅成本高昂,而且會造成糟糕的用戶體驗。在此情況下,我們通常可以自行處理配置變更,以避免系統資源變更引起Activity重啟,通過在標簽中添加android:configChanges聲明實現。android:configChanges 屬性文檔中列出該屬性的可能值。最常用的值包括 "orientation"、"screenSize" 和 "keyboardHidden” 等。

總之,為了做好Android應用的摺疊屏適配,應用應能妥善地保存界面狀態和支持配置變更,併進行詳細的測試,詳細適配指導方案可以參考官方文檔。

小程式摺疊屏適配現狀

小程式不同於原生的Android應用,微信小程式框架目前是基於webview渲染,小程式邏輯層、視圖層等進行相關視圖、組件的計算渲染時依賴於獲取到的設備尺寸數據,當屏幕尺寸發生變化時,不可避免的會造成佈局樣式的錯亂。小程式業內目前還沒有官方的摺疊屏適配方案。以健康寶微信小程式為例,發生摺疊後,不僅界面上存在問題,還存在無法從歷史任務棧中打開的問題。

圖 6 微信應用Android手機摺疊屏效果

此外,從微信開發社區我們瞭解到,有不少開發者對於小程式摺疊屏適配還是有訴求的。

圖 7 微信小程式摺疊屏適配訴求

京東小程式摺疊屏適配

1.京東小程式摺疊屏問題

京東小程式也存在元素尺寸不合適、摺疊後無法從任務棧中再次打開等問題,我們看一下京東快遞小程式的現象。

圖 8 京東小程式適配前

內屏打開小程式狀態:

圖 9 京東小程式適配前-內屏

內屏轉外屏狀態:

圖 10 京東小程式適配前-內屏轉外屏

外屏打開小程式狀態:

圖 11 京東小程式適配前-外屏

外屏轉內屏狀態:

圖 12 京東小程式適配前-外屏 轉內屏

總之,就是在無論是內屏還是外屏,初次打開時獲取到的屏幕尺寸數據是對的,小程式能按照適合的尺寸渲染元素;一旦發生摺疊,在新的狀態要麼是元素過大不適合窄屏,要麼是元素過小不適合寬屏。

那麼問題來了,為什麼在初試打開狀態頁面上的元素是大小合適的呢?

2.小程式多屏幕適配

rpx ( responsive pixel)響應單位

rpx是微信小程式獨有的、解決屏幕自適應的尺寸單位, 在小程式開發中,推薦使用rpx這種響應式的像素單位進行開發

可以根據屏幕寬度進行自適應,不論大小屏幕,規定屏幕寬為750rpx,以 iPhone6 為基準,iPhone6 的屏幕寬度為 375px,則 750rpx = 375px

真實設備獲取到的物理像素是多種多樣的,在小程式內部通過真實物理像素與375的比值得到縮放比例,真正渲染使用時再轉換為對應的像素,通過 rpx 設置元素和字體的大小,小程式在不同尺寸的屏幕下,可以實現自動適配。

3.摺疊屏問題分析

元素尺寸問題:

在摺疊屏展開狀態打開小程式,此時取到的設備尺寸等均為展開時的數據,屏幕摺疊後,元素大小沒有發生變化,但是承載小程式的容器大小變化了,屏幕變窄了,於是按照原有的尺寸,所有的佈局空間發生壓縮,導致頁面擠壓在一起。

同樣的,在外屏打開小程式時獲取到的尺寸數據是適合外屏的,再摺疊到內屏狀態時也無法及時更新到內屏的尺寸。

究其原因,在發生屏幕摺疊時,小程式沒有獲取到最新的屏幕數據,無法更新屏幕縮放比,同時沒有機制通知小程式進行重新渲染或載入。

無法重啟問題:

小程式在Android端運行在獨立的進程中,不同小程式運行在不同進程,小程式引擎具有自己獨有的管理機制。在之前屏幕摺疊後小程式被殺死進程,通過歷史任務棧無法再次拉起該進程。

4.解決思路

監聽屏幕摺疊:

1.記錄當前屏幕參數(寬、高、方向)

2.在onConfigurationChanged(Configuration newConfig)回調中獲取最新屏幕配置

當屏幕發生摺疊後,系統會將newConfig下發給應用程式,取出newConfig.orientation 、newConfig.screenWidthDp 和 newConfig.screenHeightDp , 與 之前保存的屏幕參數進行對比。如果寬、高發生變化,通常認為屏幕發生摺疊。

3.細節處理

a.由於視屏播放器全屏狀態下通常會是橫屏狀態,當從全屏狀態切回正常模式時往往會回到豎屏,這裡屏幕的 orientation 會與之前的不同,不能當做摺疊處理。

b.摺疊屏手機屏幕往往底部還有一個最近應用的快捷導航條,如果是開啟狀態,因為需要重匯的緣故,在發生摺疊後,系統會觸發兩次onConfigurationChanged(Configuration newConfig)回調,而且兩次回調的參數中 newConfig.screenHeightDp 會前後不一致,這裡需要做一下相容處理,否則會誤判為多次摺疊。

圖 13 摺疊屏導航條

圖 14 摺疊屏導航條2

不同的底部導航條

元素尺寸問題:

要解決此問題,就要在識別到屏幕尺寸發生變化時,及時通知到業務,有兩種方案:

1.局部刷新:通知業務自行刷新

這種方案可以在一定程度上保留用戶操作流程的完整,但是也存在非當前頁面無法刷新或者或退後再次刷新等問題,對用戶來說體驗一般,而且需要小程式業務的開發者來監聽頁面變化,增加了開發者的業務複雜度。

2.整體刷新:重啟小程式

這種方案是客戶端引擎監聽到設備發生摺疊時,關閉小程式,併進行重新打開。可以很好地保障頁面的重新適配,重啟行為會對用戶操作流程完整性有一定的損傷,對小程式開發者來說沒有工作量。

無法重啟問題:

針對此問題,引擎側需要避免殺死小程式所在進程,同時結合上面 2 個頁面刷新方案,綜合考慮,採用在當前進程整體刷新、重啟小程式方案。一方面解決了歷史任務棧無法重啟問題,另一方面避免了創建新進程的開銷,界面上給人的感官也更流程。

5.遇到的問題及解決方案

1.multiWindow、pictureInPicture問題

Android系統還有兩個功能就是多視窗和畫中畫模式,activity可以縮放為一個小視窗,在屏幕中顯示一小塊區域,能夠很靈活的拉伸縮放,對於此,小程式引擎忽略了視窗大小的變化,否則用戶只要一縮放就會重啟小程式,這是我們和用戶都無法接受的。這種情況下,保持不變是契合多視窗的設計初衷的,讀者在處理類似的適配方案時應當註意多視窗、畫中畫問題。

2.onConfigurationChanged多次回調問題

不同的廠商或者不同的用戶配置,會在發生摺疊時,因為狀態欄或者系統底部的虛擬按鍵等設置,觸發不同次數的onConfigurationChanged回調,回調下發的screenHeightDp數值不一致。上文已經提到,需要針對回調參數下發的newConfig數據做真正的摺疊判斷,忽略“偽配置變更”。

3.onNewIntent問題

不考慮摺疊屏的情況下,京東小程式在多棧模式下返回時並不是真正的關閉小程式,而是壓到後臺,沒有觸發activity的finish。當用戶再次打開時會觸發onNewIntent事件,這裡會進行小程式的重啟。

但是遇到摺疊屏,就會觸發onConfigurationChanged 和 onNewIntent 都回調的情況,通過查閱源代碼和列印日誌方式,我們可以發現onConfigurationChanged的回調早於onNewIntent的。所以onConfigurationChanged一旦識別到發生屏幕摺疊就會重啟小程式,在onNewIntent這裡應該避免再次重啟小程式。

4.webview和js引擎獲取屏幕寬高失真問題

在適配中我們遇到過在某些機器上“沒問題”,在其他機器上“很容易復現”的窘境。在理論和實際上,客戶端傳遞給邏輯層、視圖層的尺寸數據都沒問題,但是小程式表現上還是存在問題。經過細緻的排查,發現js引擎上有些數據的是來自於window對象的寬高數據,此數據與摺疊後的屏幕數據不一致,即webview和js引擎獲取到的設備尺寸更新不及時,造成rpx計算失準。為此,我們替換了引擎中對window寬高的使用方式,替換為屏幕真正的數據。

6.修複效果展示

通過以上措施,經過驗證,我們小程式在摺疊屏上的相關體驗達到了比較令人滿意的效果。

內屏轉外屏:

圖 15 摺疊屏適配後-內屏轉外屏

外屏轉內屏:

圖 16 摺疊屏適配後-外屏轉內屏

外屏壓後臺,再轉內屏:

圖 17 摺疊屏適配後-後臺喚起

總結

摺疊屏作為未來Android屏幕發展的新趨勢,具有很大的發展前景,做好摺疊屏相關適配支持也勢在必行。小程式相關適配已經跟隨京東主站、小家App、小家三星預裝版等發佈上線,本文是作者進行相關適配的一些心得體會,如有不足敬請見諒,歡迎交流探討。

作者:京東零售 張磊

內容來源:京東雲開發者社區


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 前言 還記得大學第一次接觸Ubuntu和Linux的時候,覺得用apt安裝想要的軟體非常方便。但是有時候出現了問題,各種報錯,自己又不懂原理,就會非常抓狂。現在稍微理解一點了,故以較為容易理解的方式記錄在這裡,方便他人。 2. 軟體包與包管理器dpkg Linux里的軟體就是一些可執行文件。就 ...
  • 背景 工作中遇到客戶反饋,上層應用UDP固定間隔100ms發包,但本地tcpdump抓包存在波動,有的數據包之間間隔107ms甚至更多,以此重新梳理了下udp的發送流程。 udp發包流程 udp_sendmsg UDP corking 是一項優化技術,允許內核將多次數據累積成單個數據報發送。在用戶程 ...
  • 如果你在 Docker 環境中使用 WebSocket 並通過 Nginx 進行代理,可能需要進行一些額外的配置才能使 WebSocket 正常工作。 下麵是一些可能會導致 WebSocket 代理失敗的問題以及相應的解決方法: 檢查 Nginx 配置 在 Nginx 配置中,確保已經正確地設置了 ...
  • TTL是 Time To Live的縮寫,該欄位指定IP包被路由器丟棄之前允許通過的最大網段數量。TTL是IPv4報頭的一個8 bit欄位。 IPv4包頭中TTL是一個8 bit欄位,它位於IPv4包的第9個位元組。如下圖所示,每一行表示 32 bit(4位元組),位從0開始編號,即0~31。 TTL的 ...
  • (工作中,Oracle常用函數) 1、序言 Oracle提供了不少內置函數,熟練使用這些函數,可以大大提高我們工作效率。函數可以接受0個或多個入參,並返回一個輸出結果。 2、Oracle函數分類 Oracle函數分為單行函數和聚合函數 單行函數:對每一個函數應用在表的記錄中時,只能輸入一行結果,返回 ...
  • Hadoop官方網站 http://hadoop.apache.org/ Hadoop運行模式 本地模式:單機運行,只是用來演示一下官方案例。生產環境不用。 偽分散式模式:也是單機運行,但是具備Hadoop集群的所有功能,一臺伺服器模擬一個分散式的環境。個別缺錢的公司用來測試,生產環境不用。 完全分 ...
  • 主機名 ip ssh免密登陸 #修改主機名 hostnamectl set-hostname node1 #修改ip地址 vim /etc/sysconfig/network-scripts/ifcfg-ens33 #node1 IPADDR="192.168.88.101" NETMASK="22 ...
  • (Oracle常用SQL) 工作中我們基本上每天都要與資料庫打交道,資料庫的知識點呢也特別多,全部記住呢也是不可能的,也沒必要把所有的記住(有些語句命令可能我們一輩子都用不到)。 所以呢在工作之餘,把工作中經常用到的一些語句整理出來,忘記的時候可以當做字典來查。 個人在工作中用Oracle資料庫比較 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...