华为小米等折叠屏适配研究

news/2024/11/7 3:40:18/

        市面上折叠屏陆续出了几款手机,我们产品也下发了适配折叠屏的需求,以下对折叠屏是撇工作做一个记录,中间也包含网络搜罗资料整理,供大家参考。

一、目前主流折叠屏机型:

厂商 型号折叠分辨率展开分辨率
华为HUAWEI Mate Xs

主屏:2480 x 1148

副屏:2480 x 892

2480 x 2200
华为HUAWEI Mate X2外屏:2700 x 11602480 x 2200
小米MIX FOLD外屏:2520 x 8402480 x 1860
三星Galaxy Z Fold2外屏:2260 x 8162208 x 1768

二、折叠屏的物理姿态:

三、折叠屏的物理切分:

四、针对折叠屏基础的适配方案:

1、屏幕兼容性的支持:

(1)应用 resizeable 能力支持

设置方法:在 manifest 文件的或节点中设置 android:resizeableActivity 的值为 true,可 声明应用支持自适应显示,Activity 将能以分屏和 freeform 模式启动。

示例代码:

android:resizeableActivity=["true" | "false"] 

   (2)增加申明应用支持的屏幕比范围

申明最大比例:

通过在 < meta-data> 添加 android.max_aspect 声明的方式

示例代码:

<meta - data android: name = "android.max_aspect"   android: value = "2.4" / >

申明最小比例

通过在 < meta-data> 添加 android.max_aspect 声明的方式

示例代码:

 < meta - data android: name = "android.min_aspect"   android: value = "1.0" / >

 2、屏幕连续性的支持:

为了保证您的应用程序在展开/折叠过程无缝切换,您需要做应用连续性的设计,以确保您的应用程序任务不中断,

以MateX 为例,最佳的体验为,应用在展开切换过程中,不发生应用的重启,且切换之前的任务和应用相关状态得以保存和延续,

折叠展开的动作,会触发对smallestscreensize、screensize和screenlayout的配置更改。通过注册监听系统configchanges消息,

不重启应用的情况下处理配置更改,您需要向manifest中添加android:configchanges属性,其中至少包含以下值:

< activity

android: name == ".MyActivity"

  android: configChanges = "screenSize|smallestScreenSize|screenLayout" / >

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

@Override

public void onConfigurationChanged(Configuration newConfig) {

    super.onConfigurationChanged(newConfig);

    Log.i("test", "newConfig.screenHeightDp:" + newConfig.screenHeightDp +

        ", newConfig.screenWidthDp" + newConfig.screenWidthDp);

    //根据屏幕分辨率信息调整应用的布局

    ...

}

2.2:我们研究过程中总结的较为通用的方案:

根据华为开发者文档提供的适配需要在每个页面和控件的 onConfigurationChanged方法中对页面进行重新布局和排版,实际测试过程中发现几乎每个页面都需要重新设置,工作量非常大,(我们使用的适配方案为smallestWidth 限定符最小宽度适配方案,在大屏幕进入页面,切换小屏幕时页面元素尺寸变得非常大,字体也非常大,因为大屏幕使用的大尺寸的dp,切换时没有自动切换sw文件夹)。后来发现在基类的attachBaseContext方法中判断是否是折叠屏的展开状态,重新设置Context,使其强制使用小屏幕的sw尺寸,代码如下:

@Override
protected void attachBaseContext(Context newBase) {super.attachBaseContext(FoldingScreenUtils.attachBaseContext(newBase));
}

 并在基类Activity的onConfigChanged回调中重新设置Context,避免小屏幕进入页面时不会调用方法,

  @Overridepublic void onConfigurationChanged(Configuration newConfig) {FoldingScreenUtils.onConfigurationChanged(this,newConfig);super.onConfigurationChanged(newConfig);}

 工具类如下:


import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.DisplayMetrics;public class FoldingScreenUtils {public static final float MAX_WIDTH_HEIGHT = 3f / 4f;/*** 会创建一个新的Context来替代baseContext用以设置sw* @param context* @return*/public static Context attachBaseContext(Context context) {if (isFoldingScreen(context)) {Resources resources = context.getResources();Configuration configuration = resources.getConfiguration();DisplayMetrics displayMetrics = resources.getDisplayMetrics();int smallestScreenWidthDp = configuration.smallestScreenWidthDp;// 8.0需要使用createConfigurationContext处理if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {return updateResources(context, smallestScreenWidthDp);} else {configuration.smallestScreenWidthDp = (int) (smallestScreenWidthDp * 0.52);resources.updateConfiguration(configuration, displayMetrics);return context;}} else {return context;}}@TargetApi(Build.VERSION_CODES.N)private static Context updateResources(Context context, int smallestScreenWidthDp) {Resources resources = context.getResources();Configuration configuration = resources.getConfiguration();configuration.smallestScreenWidthDp = (int) (smallestScreenWidthDp * 0.52);return context.createConfigurationContext(configuration);}/*** 返回当前设备是否是展开状态折叠屏,目前没有提供准确api,暂用屏幕宽高比判断.** @param context 上下文* @return 是否是折叠屏展开状态*/public static boolean isFoldingScreen(Context context) {Resources resources = context.getResources();DisplayMetrics displayMetrics = resources.getDisplayMetrics();float widthPixels = displayMetrics.widthPixels * 1.0f;float heightPixels = displayMetrics.heightPixels * 1.0f;return widthPixels / heightPixels > MAX_WIDTH_HEIGHT;}/**** 根据新屏幕参数判断是否是折叠屏宽屏状态.* @param newConfig context取值不准时拿到onConfigurationChanged中的新屏幕参数* @return 是否是折叠屏的宽屏状态*/@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB_MR2)public static boolean isFoldingScreen(Configuration newConfig) {return (float) newConfig.screenWidthDp / (float) newConfig.screenHeightDp > MAX_WIDTH_HEIGHT;}/*** 只用这个方法来更新config* @param context* @param newConfig*/public static void onConfigurationChanged(Context context, Configuration newConfig) {try {if (isFoldingScreen(context)) {newConfig.smallestScreenWidthDp = (int) (newConfig.smallestScreenWidthDp * 0.52);context.getResources().updateConfiguration(newConfig, context.getResources().getDisplayMetrics());}} catch (Exception e) {e.printStackTrace();}}
}

大家有注意到我们工具类中isFoldingScreen方法有两份重写,一个是使用activity类的Context参数取当前屏幕的宽高来判断比例,但在一些popWindow和Dialog中并不能直接实现此方法,需要在类中传入的context监听ComponentCallbacks全局的状态改变回调,

 context.registerComponentCallbacks(new ComponentCallbacks() {@Overridepublic void onConfigurationChanged(Configuration newConfig) {}@Overridepublic void onLowMemory() {}});

但是当屏幕改变时注册时的context中取出的屏幕宽高已经不准,所以需要用onConfigurationChanged中返回的newConfig对象取当前准确的屏幕尺寸来判断是否是展开状态的折叠屏,目前当前厂家和google并没有提供具体api来判断是否是折叠屏,所以暂时通过这种方法判断,同时对pad也有一定适配效果。

注意在控件销毁时做解除监听处理:

context.unregisterComponentCallbacks

 参考文档:

https://developer.huawei.com/consumer/cn/doc/90101  华为折叠屏应用开发指导

https://www.jianshu.com/p/83efb0eaeee3 Android 折叠屏适配攻略


http://www.ppmy.cn/news/232205.html

相关文章

2021 App上架到 各应用商店(应用宝,华为,vivo,小米,AppStore)

操作目录 一. 需要准备材料1.软件安装包【apk/ipa】2.软件包名/PackageName3. 软著4.营业执照5.软件隐私协议 & 软件用户服务协议6.App图标7.应用截图8. 企业法定代表人身份证正背面9. 电子版权证书10. App简介11. ICP备案号 & 域名 二. 各应用商店网址1. 应用宝2. 小米…

android 小米相册无法获取,适配小米华为手机等拍照后获取不到照片

问题摘要:适配小米华为手机等拍照后获取不到照片 出现场景 普通的相机调用,在 intent 传进去一个路径,然调用这个意图。 在测试机 荣耀 8x 上是没有问题的,能获取到拍的照片。 在小米系统和 华为麦芒4上就不行,路径上就没有照片。 /** * @param file 拍照生成的照片地址 *…

友盟推送集成小米华为通道

在集成友盟推送的时候&#xff0c;小米和华为对后台进程做了诸多限制。若使用一键清理&#xff0c;应用的channel进程被清除&#xff0c;将接收不到推送。为了增加推送的送达率&#xff0c;可选择接入小米托管弹窗功能。通知将由小米系统托管弹出&#xff0c;点击通知栏将跳转到…

小米max2android8,小米Max2和荣耀8哪个好?华为荣耀8与小米Max2区别对比评测

华为荣耀8与小米Max2区别对比评测 荣耀8介绍&#xff1a; 华为荣耀8硬件配置参数&#xff0c;详情如下所示&#xff0c;参数党必看&#xff1a; 荣耀8硬件配置参数 主屏尺寸 5.2英寸19201080像素 424ppi 机身尺寸 147.1x73.8x8.3 mm(156g) CPU型号 海思麒麟950(64位八核) RAM容…

华为荣耀9x的Android版本,华为荣耀9X评测:小米OV都坐不住了

华为荣耀9X评测&#xff1a;小米OV都坐不住了 2019-07-24 14:42:07 3点赞 0收藏 0评论 荣耀9X系列手机将在7月23日发布已经不是什么秘密&#xff0c;更何况荣耀一连几天在微博等平台上为新机造势&#xff0c;相信广大粉丝们已经大致了解荣耀9X系列手机的一些关键信息。 但尽管如…

华为荣耀5x android8,小米5X和荣耀8哪个好?华为荣耀8与小米5X区别对比评测

荣耀8介绍&#xff1a; 华为荣耀8硬件配置参数&#xff0c;详情如下所示&#xff0c;参数党必看&#xff1a; 荣耀8硬件配置参数 主屏尺寸 5.2英寸19201080像素 424ppi 机身尺寸 147.1x73.8x8.3 mm(156g) CPU型号 海思麒麟950(64位八核) RAM容量 3GB/4GB ROM容量 32GB/64GB(最大…

群智能算法-模拟退火

一.基本理念 模拟退火算法(Simulated Annealing,简称SA) 的思想最早是由Metropolis等提出的.其出发点就是基于物理中固体物质的退火过程与一般的组合优化问题之间的相似性。模拟退火法是一种通用的优化算法&#xff0c;其物理退火过程由以下三部分组成。 加温过程&#xff1a;我…

前端CSS卡片动画效果的实现

先来看看具体效果图如下&#xff1a; HTML代码如下&#xff1a; <!DOCTYPE html> <html> <head><title>【每日一练】CSS产品卡片动画效果的实现</title> </head> <body><div class"card"><div class"cover…