探索Android折叠屏设备的分屏适配

news2024/10/1 5:36:52

探索Android折叠屏设备的分屏适配

前言

随着折叠屏和大屏设备的普及,如何为这些设备提供高效的用户体验成为移动开发者的重点挑战之一。Android通过引入 androidx.window 库,为开发者提供了支持折叠屏、多任务处理和分屏功能的强大工具。本文结合实际项目中的经验,探讨如何在开发中实现分屏功能,特别是在小米设备上的实践,以及在使用 me.jessyan:autosize:1.2.1 库时遇到的分屏失效问题。

分屏适配的必要性

折叠屏设备通常具有更大的显示面积,用户希望在一个屏幕上同时处理多个任务。分屏功能不仅提高了用户的多任务处理效率,还能为复杂的应用场景提供更好的布局展示,例如:同时展示内容列表和详情页。

针对不同厂商、不同屏幕尺寸和方向的适配,分屏功能的实现仍然面临着一系列挑战。这需要我们在开发中灵活配置布局、处理分屏规则、并考虑与其他库的兼容性问题。

使用 androidx.window 实现分屏功能

在项目中,使用了 androidx.window.embedding.* 库,通过定义规则实现不同Activity之间的分屏显示。首先在 MyApplication 类中初始化分屏规则,这在全局控制分屏行为的同时,也提高了灵活性。

分屏规则的添加

通过 SplitPairRuleSplitPlaceholderRule,可以为应用不同的Activity组合创建分屏规则。以下代码展示了如何创建两个Activity之间的分屏关系,并设置它们的显示比例。

private void addSplitPairRule(RuleController ruleController) {
    Set<SplitPairFilter> filterSet = new HashSet<>();
    filterSet.add(new SplitPairFilter(
        new ComponentName(this, TestMainActivity.class),
        new ComponentName(this, TestDetailsActivity.class),
        null
    ));

    SplitAttributes splitAttributes = new SplitAttributes.Builder()
        .setSplitType(SplitAttributes.SplitType.ratio(0.5f))
        .setLayoutDirection(SplitAttributes.LayoutDirection.RIGHT_TO_LEFT)
        .build();

    SplitPairRule splitPairRule = new SplitPairRule.Builder(filterSet)
        .setDefaultSplitAttributes(splitAttributes)
        .setMinWidthDp(600)
        .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f))
        .build();

    ruleController.addRule(splitPairRule);
}

这个规则允许 TestMainActivityTestDetailsActivity 在宽度超过600dp的屏幕上以1:1的比例进行分屏显示,并指定了布局方向。

占位符规则

除了分屏规则,SplitPlaceholderRule 是实现多任务场景的利器。它允许在主Activity之外显示一个占位符Activity,在大屏或折叠屏设备上提供更好的用户体验。例如:

private void addSplitPlaceholderRule(RuleController ruleController) {
    Set<ActivityFilter> placeholderActivityFilterSet = new HashSet<>();
    placeholderActivityFilterSet.add(new ActivityFilter(
        new ComponentName(this, TestActivity.class),
        null
    ));

    Intent placeholderIntent = new Intent(this, TestDetailsActivity.class);
    SplitAttributes splitAttributes = new SplitAttributes.Builder()
        .setSplitType(SplitAttributes.SplitType.ratio(0.5f))
        .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT)
        .build();

    SplitPlaceholderRule splitPlaceholderRule = new SplitPlaceholderRule.Builder(
        placeholderActivityFilterSet, placeholderIntent)
        .setDefaultSplitAttributes(splitAttributes)
        .setMinWidthDp(600)
        .build();

    ruleController.addRule(splitPlaceholderRule);
}

兼容性与挑战

1. 设备适配问题

在小米设备上测试分屏规则,效果不错。然而,每个设备的屏幕尺寸、分辨率和折叠特性不同,在不同设备上展示的效果可能会有差异。例如,某些设备的宽度可能不满足600dp的要求,这时分屏功能将无法触发。因此,分屏规则中的最小宽度和方向必须根据设备情况灵活调整。

2. me.jessyan:autosize:1.2.1 库导致分屏失效

在实际开发中,发现如果项目中同时使用了 me.jessyan:autosize:1.2.1 库,分屏功能会失效。这是因为该库会动态调整屏幕密度和尺寸,从而影响 androidx.window 库对屏幕宽度的判断。因此,如果项目需要使用分屏功能,必须慎重考虑 autosize 的使用,或在必要时对屏幕尺寸调整进行更细粒度的控制。

一种解决方案是通过在 AndroidManifest.xml 中移除 autosize 的初始化配置来避免这种冲突:

<provider
    android:name="me.jessyan.autosize.InitProvider"
    android:authorities="${applicationId}.me.jessyan.autosize.initprovider"
    android:exported="false"
    tools:node="remove" />

关键的Manifest配置

在清单文件中,需要确保每个Activity支持动态调整屏幕方向并启用分屏功能,尤其是对于折叠屏设备。以下是项目中的 AndroidManifest.xml 配置片段:

<activity
    android:name=".activity.TestActivity"
    android:configChanges="orientation|screenSize"
    android:resizeableActivity="true"
    android:screenOrientation="unspecified">
</activity>

这个配置允许应用在屏幕方向改变时,动态调整布局并启用分屏功能。分屏的触发与Activity是否声明 resizeableActivity="true" 密切相关。

创建自定义分屏管理器

1.定义分屏管理器

在开始编码之前,首先需要创建一个分屏管理器类,用于管理所有的分屏规则。

public class SplitRuleManager {
    private RuleController ruleController;

    public SplitRuleManager(RuleController ruleController) {
        this.ruleController = ruleController;
    }

    public void addSplitPairRule(Class<?> primary, Class<?> secondary, float ratio) {
        Set<SplitPairFilter> filterSet = new HashSet<>();
        filterSet.add(new SplitPairFilter(
                new ComponentName(MyApplication.this, primary),
                new ComponentName(MyApplication.this, secondary),
                null
        ));

        SplitAttributes splitAttributes = new SplitAttributes.Builder()
                .setSplitType(SplitAttributes.SplitType.ratio(ratio))
                .build();

        SplitPairRule splitPairRule = new SplitPairRule.Builder(filterSet)
                .setDefaultSplitAttributes(splitAttributes)
                .build();

        ruleController.addRule(splitPairRule);
    }
}
2.在Application类中使用分屏管理器

MyApplication类中,可以初始化分屏管理器,并在onCreate()方法中添加分屏规则。

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        RuleController ruleController = RuleController.getInstance(this);
        SplitRuleManager splitRuleManager = new SplitRuleManager(ruleController);
        
        // 添加分屏规则
        splitRuleManager.addSplitPairRule(TestMainActivity.class, TestDetailsActivity.class, 0.5f);
        splitRuleManager.addSplitPairRule(TestDetailsActivity.class, TestDetails1Activity.class, 0.5f);
        // 可根据需求继续添加更多规则
    }
}

处理状态和生命周期

在分屏模式下,Activity的生命周期和状态管理尤为重要。开发者需要处理Activity的启动、暂停、恢复等状态,以确保用户体验的流畅性。

实际开发中的注意事项

1. 兼容性问题

分屏功能的实现可能会受到不同设备、Android版本的影响。在实际开发中,应充分测试应用在各种设备上的表现,确保功能的稳定性。

2 .性能优化

分屏模式下同时运行多个Activity可能会对性能产生影响。开发者应关注内存管理和资源释放,以避免应用卡顿或崩溃。

3. 自适应布局

使用ConstraintLayout等自适应布局,可以更好地适应不同屏幕尺寸和方向,从而提升用户体验。

4. 库的影响

如使用me.jessyan:autosize:1.2.1库时,可能会导致分屏功能失效。在这种情况下,需要根据项目需求考虑使用或替代其他布局自适应方案。

总结

在Android折叠屏设备上实现分屏功能是一项具有挑战性的任务,但也是提升用户体验的重要一步。在实际开发中,灵活定义分屏规则、兼顾设备适配性,并处理与第三方库的冲突,是确保分屏功能顺利实现的关键。希望通过这篇文章,能为你提供一些启发和实用的解决方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2181610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

66 使用注意力机制的seq2seq_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录动机加入注意力总结代码定义注意力解码器训练小结练习 我们来真的看一下实际应用中&#xff0c;key&#xff0c;value&#xff0c;query是什么东西&#xff0c;但是取决于应用场景不同&#xff0c;这三个东西会产生变化。先将放在seq2seq这个…

使用 SSH 连接 Docker 服务器:IntelliJ IDEA 高效配置与操作指南

使用 SSH 连接 Docker 服务器&#xff1a;IntelliJ IDEA 高效配置与操作指南 本文详细介绍了如何在 2375 端口未开放的情况下&#xff0c;通过 SSH 连接 Docker 服务器并在 Idea 中进行开发。通过修改用户权限、生成密钥对以及配置 SSH 访问&#xff0c;用户可以安全地远程操作…

Ubuntu 系统崩了,如何把数据拷下来

问题描述&#xff1a; Linux系统中安装输入法后&#xff0c;重启后&#xff0c;导致系统无法进入&#xff0c;进入 recovery mode下的resume 也启动不了&#xff0c;所以决定将需要的东西复制到U盘 解决方案&#xff1a; 1.重启ubuntu&#xff0c;随即点按Esc进入grub菜单&am…

Linux shell脚本set -e的作用详解

文章目录 功能详细解释示例不使用 set -e 的情况总结 set -e 是一个用于控制脚本行为的命令&#xff0c;它的作用是&#xff1a; 功能 当脚本运行时&#xff0c;set -e 会确保一旦某个命令返回非零的退出状态&#xff08;即执行失败&#xff09;&#xff0c;整个脚本会立即停止…

Docker面试-24年

1、Docker 是什么&#xff1f; Docker一个开源的应用容器引擎&#xff0c;是实现容器技术的一种工具&#xff0c;让开发者可以打包他们的应用以及环境到一个镜像中&#xff0c;可以快速的发布到任何流行的操作系统上。 2、Docker的三大核心是什么? 镜像&#xff1a;Docker的…

在 Kali Linux 中安装 Impacket

步骤 1&#xff1a;更新系统 打开终端并确保你的系统是最新的&#xff1a; sudo apt update && sudo apt upgrade -y 步骤 2&#xff1a;安装依赖 在安装 Impacket 之前&#xff0c;你需要确保安装了 Python 和一些必要的依赖。通常&#xff0c;Kali 已经预装了 Pytho…

工作日志:el-table在无数据情况下,出现横向滚动条。

1、遇到一个警告。 原因&#xff1a;中的组件不能呈现动画的非元素根节点。 也就是说&#xff0c;Transition包裹的必须是一个单根的组件。 2、el-table在无数据情况下&#xff0c;出现横向滚动条&#xff0c;大概跟边框的设置有关系。 开始排查。 给.el-scrollbar加了一个…

Linux 线程同步

前言 上一期我们介绍了线程互斥&#xff0c;并通过加锁解决了多线程并发访问下的数据不一致问题&#xff01;本期我们来介绍一下同步问题&#xff01; 目录 前言 一、线程同步 • 线程同步的引入 • 同步的概念 理解同步和饥饿问题 • 条件变量 理解条件变量 • 同步…

TypeScript 算法手册 【数组基础知识】

文章目录 1. 数组简介1.1 数组定义1.2 数组特点 2. 数组的基本操作2.1 访问元素2.2 添加元素2.3 删除元素2.4 修改元素2.5 查找元素 3. 数组的常见方法3.1 数组的创建3.2 数组的遍历3.3 数组的映射3.4 数组的过滤3.5 数组的归约3.6 数组的查找3.7 数组的排序3.8 数组的反转3.9 …

AI写作赋能数据采集,开启无限可能性

由人工智能 AI 掀起的新一轮科技革命浪潮&#xff0c;正在不断推动社会进步、各行各业升级发展&#xff0c;深刻影响人们的生活方式&#xff0c;引领我们进入一个充满无限可能的新时代。 那么在数据采集方面&#xff0c;人工智能 AI 可以做什么呢&#xff1f; 下面是搜集网络…

开源在线表结构设计工具

Free, simple, and intuitive database design tool and SQL generator. drawDB在线体验 Discord X drawDB DrawDB is a robust and user-friendly database entity relationship (DBER) editor right in your browser. Build diagrams with a few clicks, export sql scri…

若依--文件上传前端

前端 ry的前端文件上传单独写了一个FileUpload.Vue文件。在main.js中进行了全局的注册&#xff0c;可以在页面中直接使用文件上传的组件。全局导入 在main.js中 import 组件名称 from /components/FileUpLoadapp.compoent(组件名称) //全局挂载组件在项目中使用 组件命令 中…

定时器定时中断定时器外部中断

TIM的函数 // 恢复缺省设置 void TIM_DeInit(TIM_TypeDef* TIMx); // 时基单元初始化&#xff0c;第一个参数TIMx选择某个定时器&#xff0c;第二个参数是结构体&#xff0c;包含了配置时基单元的一些参数。 void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDe…

28 Vue3之搭建公司级项目规范

可以看到保存的时候ref这行被提到了最前面的一行 要求内置库放在组件的前面称为auto fix&#xff0c;数组new arry改成了字面量&#xff0c;这就是我们配置的规范 js规范使用的是airbnb规范模块使用的是antfu 组合prettier&eslint airbnb规范&#xff1a; https://github…

《More Effective C++》的学习

引用与指针 没有所谓的null reference reference一定需要代表某个对象&#xff0c;所以C要求reference必须有初值。 QString &s; 使用reference可能比使用pointer更高效。 因为reference一定是有效的&#xff0c;而指针可能为空&#xff08;需要多加一个判断&#xff0…

Springboot3 + MyBatis-Plus + MySql + Vue + ProTable + TS 实现后台管理商品分类(最新教程附源码)

Springboot3 MyBatis-Plus MySql Uniapp 商品加入购物车功能实现&#xff08;针对上一篇sku&#xff09; 1、效果展示2、数据库设计3、后端源码3.1 application.yml 方便 AliOssUtil.java 读取3.2 model 层3.2.1 BaseEntity3.2.1 GoodsType3.2.3 GoodsTypeSonVo3.3 Controll…

论文翻译 | LLaMA-Adapter :具有零初始化注意的语言模型的有效微调

摘要 我们提出了一种轻量级的自适应方法&#xff0c;可以有效地将LLaMA微调为指令遵循模型。lama - adapter采用52K自指导演示&#xff0c;在冻结的LLaMA 7B模型上只引入1.2M可学习参数&#xff0c;在8个A100 gpu上进行微调花费不到一个小时。具体来说&#xff0c;我们采用了一…

Vue3+Antv X6流程图基本使用

安装 antv/X6 npm i antv/x6 <template><div class"homes"><div class"Shang">上</div><div class"Zhong"><div id"container"></div></div><div class"Xia">下<…

wordpress Contact form 7发件人邮箱设置

此教程仅适用于演示站有留言的主题&#xff0c;演示站没有留言的主题&#xff0c;就别往下看了&#xff0c;免费浪费时间。 使用了Contact form 7插件的简站WordPress主题&#xff0c;在有人留言时&#xff0c;就会发邮件到网站的系统邮箱(一般与管理员邮箱为同一个)里。上面显…

Java | Leetcode Java题解之第448题找到所有数组中消失的数字

题目&#xff1a; 题解&#xff1a; class Solution {public List<Integer> findDisappearedNumbers(int[] nums) {int n nums.length;for (int num : nums) {int x (num - 1) % n;nums[x] n;}List<Integer> ret new ArrayList<Integer>();for (int i …