At the beginning of this year, we released the alpha02 version of the Jetpack WindowManager library. This is a major version update and contains some deprecated APIs (currently released to version 1.0.0-alpha09). This article will review this for you The content of the version update.
The Jetpack WindowManager library can help you build applications that can sense new device features such as folding and hinges, and use new features that didn't exist before. When developing the Jetpack WindowManager library, we combined developer feedback and continued to iterate the API in the Alpha version to provide a cleaner and complete API interface. We have been paying attention to different areas in the WindowManager space to provide more functions. We have introduced WindowMetrics so that you can use these new API Android 11 in Android 4.1 (API level 16) and above.
After the first version was released, we spent a lot of time analyzing developer feedback and made a lot of updates in the alpha02 version. Next, let's look at the specific content updated in the alpha02 version!
Create a new WindowManager
The Alpha02 version provides a simple constructor. This constructor has only one parameter, which points to the Context of a visible entity (such as the currently displayed Activity):
val windowManager = WindowManager(context: Context)
original constructor ) can still be used, but has been marked as obsolete:
@Deprecated
val windowManager = WindowManager(context: Context, windowBackend: WindowBackend?)
When you want to use a custom WindowBackend to simulate a foldable device on a common device or simulator, you can use the original constructor for testing. The this 160f135830fab1 sample project can be used for your reference.
In the alpha02 version, you can still pass the parameter WindowBackend as null. We plan to set WindowBackend as a required parameter in a future version and remove the deprecation flag to promote the use of this interface during testing.
Add DisplayFeature and deprecate DeviceState
Another major change is the deprecation of the DeviceState
class, and the use of it to notify your app's callbacks. The reason for this is that we want to provide more general APIs that allow the system to return all available DisplayFeature instances to your application instead of defining the global device state. We have removed DeviceState from the public API in the alpha06 version, please use FoldingFeature instead.
The alpha02 version introduces the new DisplayFeature
class with an updated callback protocol to notify your application when DisplayFeature
You can register and unregister callbacks to use these methods:
registerLayoutChangeCallback(@NonNull Executor executor, @NonNull Consumer<WindowLayoutInfo> callback)
unregisterLayoutChangeCallback(@NonNull Consumer<WindowLayoutInfo> callback)
WindowLayoutInfo
contains a list DisplayFeature
instances located in the window.
FoldingFeature
class implements the DisplayFeature
interface, which contains information about the following types of functions:
TYPE_FOLD(折叠类型)
TYPE_HINGE(铰链类型)
The possible folding states of the device are as follows:
△ DisplayFeature possible states: fully expanded, half open, flipped
It should be noted that there is no state corresponding to the POSTURE_UNKNOWN and POSTURE_CLOSED postures in DeviceState.
To get the latest status information, you can use the FoldingFeature
information returned by the registered callback:
class LayoutStateChangeCallback : Consumer<WindowLayoutInfo> {
override fun accept(newLayoutInfo: WindowLayoutInfo) {
// 检查 newLayoutInfo. getDisplayFeatures() 的返回值,
// 看它是否为 FoldingFeature 实例,并获取其中的信息。
}
}
How to use this information, please refer to: https://github.com/android/user-interface-samples/tree/main/WindowManager .
Better callback registration
The callback API of the above sample code is also more robust. In previous versions, if the application registered a callback before the window was available, an exception would be thrown.
In the aplha02 version, we modified the above behavior. You can register for these callbacks whenever it is useful for your application design, and the library will send the initial WindowLayoutInfo when the window is available.
R8 rule
We have added R8's "keep" rule to the library to keep those methods or classes that may be deleted due to the organizational structure of internal modules. These rules will be automatically merged into the final R8 rules of the application, which can prevent the application from crashing like the alpha01 version.
WindowMetrics
Due to historical naming conventions and various possible Window Manager states, it is difficult to obtain the current window size information on Android. Some obsolete methods in Android 11 (such as Display#getSize
and Display#getMetrics) and the use of new APIs in the window size all highlight the rising trend of foldable devices from full screen to multi-window and adaptive windows. To simplify this transition process, we have added WindowMetrics API in Android 11.
Before the first layout is completed, WindowMetrics allows you to easily obtain the current window state information and the maximum Window size information in the current state of the system. For example, for devices like Surface Duo, the device will have a default configuration that determines which screen the application starts from, but it can also be extended to two screens across the hinge of the device. In the default state, the'getMaximumWindowMetrics' method returns the boundary information of the screen where the application is currently located. When the application is moved to a multi-screen state, the'getMaximumWindowMetrics' method returns the boundary information reflecting the new state. This information will be provided during onCreate as early as possible, and your Activity can use this information to calculate or make decisions as early as possible so that you can choose the right layout at the first time.
The result returned by the API does not include system inset information, such as the status bar or navigation bar. This is because in all currently supported Android versions, the area corresponding to these values is not available until the first layout is completed. Regarding using ViewCompat to obtain system available inset information, Chris Banes' article- Handling Visual Conflicts | Gesture Navigation (2) is a very good resource. The boundary information returned by the API also does not respond to layout parameters that may change when the layout is filled.
To access these APIs, you need to first obtain a WindowManager object as explained above:
val windowManager = WindowManager(context: Context)
Now you can access WindowMetrics API and easily get the current window size and maximum size information.
windowManager.currentWindowMetrics
windowManager.maximumWindowMetrics
For example, if the layout or navigation mode of your app on your phone and tablet is very different, you can rely on this information to make a layout selection before the view is populated. If you think that users will be confused about the obvious changes in the layout, you can ignore the changes in the current window size information and select some of the information as constants. Before choosing which to fill, you can use the window maximum size information.
Although the Android 11 platform already includes an API for getting inset information during onCreate, we have not added this API to the WindowManager library because we want to know which of these functions are useful to developers. You can give us positive feedback so that we know what values or abstractions we need to know that make it easier to write layouts before you lay out for the first time.
We hope that these APIs that can be used on lower versions of Android can help you build applications that respond to window size changes and help you replace the obsolete APIs mentioned above.
Contact us
We very much hope to get your feedback on these APIs, especially those you think are missing, or those that can make your development easier. There are some usage scenarios that we may not consider, so we hope you submit bugs or functional requirements to us public tracker
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。