当前位置:网站首页>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?请在评论中分享您的想法.
边栏推荐
- mysql去除重复数据
- 数据指标口径不统一、重复开发?亿信ABI指标管理平台帮你解决
- Be careful with your dictionaries and boilerplate code
- Outsourcing worked for three years, it was abolished...
- CISP-PTE真题演示
- DistSQL in-depth analysis: creating a dynamic distributed database
- TransGAN代码复现—九天毕昇平台
- 大家都在用的plm项目管理软件有哪些
- GPGGA NTRIP RTCM 笔记
- 基于ABP实现DDD--实体创建和更新
猜你喜欢

数据指标口径不统一、重复开发?亿信ABI指标管理平台帮你解决

Image Restoration by Estimating Frequency Distribution of Local Patches

Teach you how to build a permanently running personal server

A simple rich text editor

类和对象——上

LeetCode·每日一题·952.按公因数计算最大组件大小·并查集
![[Machine Learning] The Beauty of Mathematics Behind Gradient Descent](/img/63/c9d5d9370c28dbce0195e1ff26869b.jpg)
[Machine Learning] The Beauty of Mathematics Behind Gradient Descent

关于MySQL主从复制的数据同步延迟问题

Enhancing Quality for HEVC Compressed Videos

GPGGA NTRIP RTCM Notes
随机推荐
系统结构考点之并行主存
Deep Non-Local Kalman Network for VideoCompression Artifact Reduction
MySQL Soul 16 Questions, How Many Questions Can You Last?
GPGGA NTRIP RTCM 笔记
用于视频压缩伪影消除的深度卡尔曼滤波网络
y82.第四章 Prometheus大厂监控体系及实战 -- 监控扩展和prometheus 联邦(十三)
手动从0搭建ABP框架-ABP官方完整解决方案和手动搭建简化解决方案实践
Motion Tuned Spatio-temporal Quality Assessmentof Natural Videos
JDBC (detailed explanation)
[Deep Learning] Understanding of Domain Adaptation in Transfer Learning and Introduction of 3 Techniques
系统结构考点之CRAY-1向量处理机
【Nacos】解决Nacos下载速度缓慢的问题
[Limited Time Bonus] 21-Day Learning Challenge - MySQL from entry to mastery
Quick Master QML Chapter 6 Animation
对List集合中每个对象元素按时间顺序排序
MySQL压缩包方式安装,傻瓜式教学
MySQL user authorization
cmd(命令行)操作或连接mysql数据库,以及创建数据库与表
牛客网——业务分析-提取值
About the error of SFML Rect.inl file