当前位置:网站首页>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?请在评论中分享您的想法.
边栏推荐
- TransGAN code reproduction - Jiutian Bisheng Platform
- MySQL Soul 16 Questions, How Many Questions Can You Last?
- 新书上市 |《谁在掷骰子?》在“不确定性时代”中确定前行
- 登堂入室之soc开发makefile
- 基于ABP实现DDD--领域服务、应用服务和DTO实践
- ELF:加载过程
- GPGGA NTRIP RTCM 笔记
- IDEA2018.3.5 cancel double-click Shift shortcut
- Solve the problem of centos8 MySQL password ERROR 1820 (HY000) You must reset your password using the ALTER USER
- JDBC (detailed explanation)
猜你喜欢
随机推荐
Qt 同时生成动态库和静态库
Google Earth Engine ——
(7/29)基础板子最小生成树prim+kruskal
系统结构考点之CRAY-1向量处理机
数据质量提升
The Road to Ad Monetization for Uni-app Mini Program Apps: Rewarded Video Ads
go语言慢速入门——流程控制语句
cookie和session区别
Solve npm warn config global `--global`, `--local` are deprecated. use `--location=global` instead
JUC原子类详解
kubernetes
JDBC (detailed explanation)
Niu Ke Xiaobaiyue Race 53 A-E
MySQL 游标
系统结构考点之流水线向量点积
【Network Security Column Directory】--Penguin Column Navigation
Apache DolphinScheduler新一代分布式工作流任务调度平台实战-
MySQL分页查询的5种方法
Typescript 严格模式有多严格?
Automatically generate test modules using JUnit4 and JUnitGenerator V2.0 in IDEA









