当前位置:网站首页>Collapse legacy apps
Collapse legacy apps
2022-07-30 21:36:00 【yihanss】
前言
This series focuses on foldable and large-screen devices.Most of its articles use it Kotlin,It has become a few years ago Android The preferred programming language for the application.然而,There is still a lot to base on Java 的 Android 应用程序.Calling them legacy applications doesn't mean they're no longer under active development,Or at least in maintenance mode.因此,Shouldn't we make sure they also provide a great experience on new device categories?Of course we should.因此,在本文中,我将向您展示如何使用Views 使 Java Android Apps perform well on foldable devices and large screens.
Jetpack 窗口管理器
使用Jetpack WindowManager,You can query certain device characteristics related to foldable devices.例如,The library will tell you if the device has a hinge,And whether that hinge blocks certain areas of the screen.例如,双屏设备Surface DuoThis is the case with its successors.
Jetpack WindowManager使用基于Flows 的 Kotlin 友好 api.幸运的是,it also gives Java 一些爱.要在 Java 应用程序中使用该库,You need to be at the module levelbuild.gradleAdd implementation dependencies to the file:
implementation "androidx.window:window-java:1.0.0-rc01"
The next step is to make sure your app starts from Jetpack WindowManager接收信息.首先,Let's declare an instance variable:
private WindowInfoTrackerCallbackAdapter adapter;
It is initialized at the following locationonCreate():
adapter = new WindowInfoTrackerCallbackAdapter(
WindowInfoTracker.Companion.getOrCreate(
this
)
);
Now it's time to connect it with our code.为简洁起见,I use old styleActivity回调,But please consider usingJetpack
Lifecycle.
@Override
protected void onStart() {
super.onStart();
adapter.addWindowLayoutInfoListener(this,
ContextCompat.getMainExecutor(this),
callback);
…
}
@Override
protected void onStop() {
super.onStop();
adapter.removeWindowLayoutInfoListener(callback);
…
}
那么,什么是callback?
private final Consumer<WindowLayoutInfo> callback =
(windowLayoutInfo -> {
final var windowMetrics = WindowMetricsCalculator.getOrCreate()
.computeCurrentWindowMetrics(this);
final var windowWidth = windowMetrics.getBounds().width();
final var windowHeight = windowMetrics.getBounds().height();
final var leftPaneParams = binding.leftPane.getLayoutParams();
final var rightPaneParams = binding.rightPane.getLayoutParams();
final var hingeParams = binding.hinge.getLayoutParams();
var hasFoldingFeature = false;
List<DisplayFeature> displayFeatures
= windowLayoutInfo.getDisplayFeatures();
…
});
首先,We set several variables.WindowMetricsCalculatorHelp us to get the window indicator.所以,windowWidth并windowHeight包含宽度和高度.那么leftPane,rightPane和hinge呢?
布局结构
leftPane并rightPaneRepresents the content of your application,Presented in two columns.hingeplaced between them.These three linear layouts,LinearLayout如果需要,Their direction will change.I'll show you soon.
现在,您可能在想,But my app doesn't use this structure.
我知道.Most legacy apps are not optimized for tablets.But that's the beauty of this simple approach.Just create the root directory of the UIleftPane,添加hingeandrightPaneand wrap all three in oneLinearLayout. If your application relies heavily on Fragments,A larger amount of rework may then be required.
现在,让我们看看如何处理displayFeatures.
for (DisplayFeature displayFeature : displayFeatures) {
FoldingFeature foldingFeature =
(FoldingFeature) displayFeature;
if (foldingFeature != null) {
hasFoldingFeature = true;
boolean isVertical = foldingFeature.getOrientation()
== FoldingFeature.Orientation.VERTICAL;
final var foldingFeatureBounds = foldingFeature.getBounds();
hingeParams.width = foldingFeatureBounds.width();
hingeParams.height = foldingFeatureBounds.height();
if (isVertical) {
binding.parent.setOrientation(LinearLayout.HORIZONTAL);
leftPaneParams.width = foldingFeatureBounds.left;
leftPaneParams.height =
LinearLayout.LayoutParams.MATCH_PARENT;
rightPaneParams.width = windowWidth
- foldingFeatureBounds.right;
rightPaneParams.height =
LinearLayout.LayoutParams.MATCH_PARENT;
} else {
int[] intArray = new int[2];
binding.leftPane.getLocationOnScreen(intArray);
binding.parent.setOrientation(LinearLayout.VERTICAL);
leftPaneParams.width =
LinearLayout.LayoutParams.MATCH_PARENT;
leftPaneParams.height =
foldingFeatureBounds.top - intArray[1];
rightPaneParams.width =
LinearLayout.LayoutParams.MATCH_PARENT;
rightPaneParams.height = windowHeight
- foldingFeatureBounds.bottom;
}
}
}
…
那么,这里发生了什么?If we find the hinge,我们
- 设置
leftPane,rightPane, 和hingecorresponding size LieaerLayoutConfigure the orientation according to the configuration of the hinge
你注意到了getLocationOnScreen()吗?This code executes when the orientation of the hinge is horizontal.然后,leftPane和rightPaneare arranged vertically,hinge在它们之间.Although both screens are usually the same size,But a screen will contain a status bar and an app bar,So the area of content will be smaller.I've found that calculating the offset this way is the most reliable.
Our final step is to deal with the absence of hinges.This is the case with regular smartphones and tablets.
if (!hasFoldingFeature) {
final float density =
getResources().getDisplayMetrics().density;
final float dp = windowMetrics.getBounds().width() / density;
binding.parent.setOrientation(LinearLayout.HORIZONTAL);
hingeParams.width = 0;
hingeParams.height = 0;
if (dp >= 600) {
leftPaneParams.width = windowWidth / 2;
leftPaneParams.height =
LinearLayout.LayoutParams.MATCH_PARENT;
rightPaneParams.width = windowWidth / 2;
rightPaneParams.height =
LinearLayout.LayoutParams.MATCH_PARENT;
} else {
leftPaneParams.width =
LinearLayout.LayoutParams.MATCH_PARENT;
leftPaneParams.height =
LinearLayout.LayoutParams.MATCH_PARENT;
rightPaneParams.width = 0;
rightPaneParams.height = 0;
}
}
I decide if I want to use two-column mode by calculating the screen width in density independent pixels.If the calculated value is less than 600,I would configure a single column layout.否则leftPane,rightPane将具有相同的大小.在任何情况下,The hinge sizes are all set to 0.
结论
在本文中,I showed you howJetpack WindowManager合并到 Java Android 应用程序中.在许多情况下,Updating an existing layout to support two-column mode on foldable and large-screen devices is straightforward.
Are you making legacy apps look good on foldable devices?请在评论中分享您的想法.
边栏推荐
- 关于SFML Rect.inl文件报错的问题
- 活动推荐 | 2022年深圳最值得参加的边缘计算活动
- MySQL 8.0.29 解压版安装教程(亲测有效)
- JDBC (detailed explanation)
- mysql remove duplicate data
- MySQL 用户授权
- Solve the problem of centos8 MySQL password ERROR 1820 (HY000) You must reset your password using the ALTER USER
- 一个网络两种用途!南开&哈工程提出TINet,通过细化纹理和边缘,在显著性目标检测和伪装目标检测上实现双SOTA!...
- navicat连接MySQL报错:1045 - Access denied for user ‘root‘@‘localhost‘ (using password YES)
- 关于MySQL主从复制的数据同步延迟问题
猜你喜欢

LeetCode·每日一题·952.按公因数计算最大组件大小·并查集

MySQL 游标

解决centos8 MySQL密码问题ERROR 1820 (HY000) You must reset your password using ALTER USER

Image Restoration by Estimating Frequency Distribution of Local Patches

新书上市 |《谁在掷骰子?》在“不确定性时代”中确定前行

面试难题:分布式 Session 实现难点,这篇就够!

MySQL 8.0.29 设置和修改默认密码
![[Deep Learning] Target Detection | SSD Principle and Implementation](/img/07/ea4ff3ffbe7e0c11ff7baec0e1818f.jpg)
[Deep Learning] Target Detection | SSD Principle and Implementation

How strict Typescript strict mode?

基于ABP实现DDD--领域服务、应用服务和DTO实践
随机推荐
Image Restoration by Estimating Frequency Distribution of Local Patches
navicat新建数据库
牛客小白月赛53 A-E
MySQL 有这一篇就够(呕心狂敲37k字,只为博君一点赞!!!)
【问题】Mysql Waiting for table metadata lock 解决方案 修改lock_wait_timeout时间
Outsourcing worked for three years, it was abolished...
【零代码工具】15 款企业级零代码开发平台推荐,总有一款是你心仪的
NEOVIM下载安装与配置
拿什么来保护数据安全?基层数据安全体系建设待提升
大家都在用的plm项目管理软件有哪些
ML.NET相关资源整理
ELF:加载过程
Google Earth Engine ——ee.List.sequence函数的使用
ClickHouse删除数据之delete问题详解
Advanced c language: pointers (5)
Niu Ke Xiaobaiyue Race 53 A-E
数据质量提升
JSESSIONID description in cookie
深入浅出富文本编辑器
微信公众号授权登录后报redirect_uri参数错误的问题