当前位置:网站首页>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.WindowMetricsCalculator
Help us to get the window indicator.所以,windowWidth
并windowHeight
包含宽度和高度.那么leftPane
,rightPane
和hinge
呢?
布局结构
leftPane
并rightPane
Represents the content of your application,Presented in two columns.hinge
placed 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
,添加hingeandrightPane
and 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
, 和hinge
corresponding size LieaerLayout
Configure the orientation according to the configuration of the hinge
你注意到了getLocationOnScreen()
吗?This code executes when the orientation of the hinge is horizontal.然后,leftPane
和rightPane
are 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?请在评论中分享您的想法.
边栏推荐
- TransGAN code reproduction - Jiutian Bisheng Platform
- Enhancing Quality for HEVC Compressed Videos
- mysql deadlock
- GPGGA NTRIP RTCM 笔记
- Detailed explanation of the delete problem of ClickHouse delete data
- 微信公众号授权登录后报redirect_uri参数错误的问题
- A simple rich text editor
- 【问题】Mysql Waiting for table metadata lock 解决方案 修改lock_wait_timeout时间
- 用于视频压缩伪影消除的深度卡尔曼滤波网络
- 手动从0搭建ABP框架-ABP官方完整解决方案和手动搭建简化解决方案实践
猜你喜欢
随机推荐
How strict Typescript strict mode?
这本记述40年前历史的游戏书,预言的却是当下的事
【信息安全技术】RSA算法的研究及不同优化策略的比较
ClickHouse删除数据之delete问题详解
牛客网——业务分析-提取值
牛客小白月赛53 A-E
3 minutes to take you to understand WeChat applet development
【零代码工具】15 款企业级零代码开发平台推荐,总有一款是你心仪的
Automatically generate test modules using JUnit4 and JUnitGenerator V2.0 in IDEA
mysql remove duplicate data
Day 16 of HCIP
Deep Kalman Filter Network for Video Compression Artifact Removal
Detailed explanation of the delete problem of ClickHouse delete data
DPW-SDNet: Dual Pixel-Wavelet Domain Deep CNNsfor Soft Decoding of JPEG-Compressed Images
Uni-app 小程序 App 的广告变现之路:激励视频广告
我是如何让公司后台管理系统焕然一新的(上) -性能优化
数据指标口径不统一、重复开发?亿信ABI指标管理平台帮你解决
手动从0搭建ABP框架-ABP官方完整解决方案和手动搭建简化解决方案实践
The reason for not using bs4 is that the name is too long?Crawl lottery lottery information
Generate OOM records in a production environment. Conclusion: Don't be lazy to query useless fields unless you are completely sure.