Foldable Screen Adaptation Strategies in the Quanmin Karaoke Android App
The article examines how the Quanmin Karaoke Android app can adapt to foldable screens by handling configuration changes, updating layout and video sizing, avoiding UI recreation glitches, and employing strategies such as fill‑adaptation, multi‑window, compatibility modes, with testing via ADB commands and emulator profiles.
This article discusses the rapid development of mobile screens, especially the emergence of foldable displays, and presents the challenges and solutions for adapting the Quanmin Karaoke app to foldable screens.
Foldable Screen Basics
Foldable screens use flexible technology that allows the display to be folded and unfolded. Devices from Huawei and Samsung are typical examples. Folding can be internal, external, double, or multi‑fold, causing changes in screen size and physical characteristics that affect app layout.
The main goal of foldable‑screen adaptation is to ensure that the app presents data reasonably regardless of changes in screen dimensions, density, orientation, or layout.
Optimization Effects
The article shows before‑and‑after comparisons of the app’s UI on foldable devices. After optimization, video containers adapt to both folded and unfolded states, maintaining proper aspect ratios and centering.
On the home page (fixed container size), the video width always fills the screen while the height adapts and centers.
On the detail page (fixed width, variable height), the container height is minimized when folded, and the video is centered; when unfolded, the video width fills the screen, height adapts, and the container expands automatically.
Abnormal Phenomena and System Handling
When the foldable screen changes, the system performs automatic re‑creation of UI components, which can lead to non‑smooth experiences or visual glitches. Two common issues are:
UI destruction and recreation causing stutter.
Recreated UI displays incorrectly, degrading user experience.
In Quanmin Karaoke, both problems exist because the app does not fully adapt to screen‑size changes.
Interface Re‑creation Behavior
During folding or closing, the UI may disappear temporarily and then restore, sometimes losing data.
Interface Display Anomalies
Some content displays incorrectly due to hard‑coded width/height values in the initialization logic.
System Fallback
If the app cannot handle configuration changes, Android destroys the current activity and recreates it with new parameters. This is acceptable for simple pages like settings, but for complex pages it can cause data loss and visible white/black screens.
@Override
public void onSaveInstanceState(Bundle outState) {
LogUtil.i(TAG, "onSaveInstanceState:" + this);
}Developers can use onSaveInstanceState , ViewModel , or persistent storage to preserve UI state.
Better Adaptation Solutions
The recommended approach is to handle configuration changes manually. Strategies include:
Fill‑adaptation mode (used by Quanmin Karaoke).
Multi‑window mode.
In‑app split‑screen mode.
Compatibility mode.
Fill‑Adaptation Mode
In this mode, the app adjusts its layout whenever the screen changes, ensuring a reasonable visual experience.
<meta-data android:name="android.max_aspect" android:value="2.7"/>
<meta-data android:name="android.min_aspect" android:value="1.0"/>Manifest configuration:
<activity android:name="com.tencent.karaoke.module.detail.ui.DetailActivity"
android:configChanges="keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"/>The android:configChanges attribute now includes smallestScreenSize and screenLayout to capture foldable‑screen changes.
System Update Flow
When the screen folds, Android forces a new measurement and layout pass for the root view and its children. The update order is:
Update Activity configuration.
Update View tree configuration.
Update Application configuration.
// ViewRootImpl
public void updateConfiguration(int newDisplayId) {
final int lastLayoutDirection = mLastConfigurationFromResources.getLayoutDirection();
final int currentLayoutDirection = config.getLayoutDirection();
mLastConfigurationFromResources.setTo(config);
if (lastLayoutDirection != currentLayoutDirection && mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) {
mView.setLayoutDirection(currentLayoutDirection);
}
mView.dispatchConfigurationChanged(config);
requestLayout();
}Video Content Adaptation
Quanmin Karaoke contains many video and image displays. The adaptation strategy follows three principles:
Display the video as completely as possible without overflow.
Utilize the available screen height (screen height minus top bar, bottom bar, and controls).
Maintain a minimum height for narrow videos to ensure lyric display and controls.
The app calculates container and video dimensions based on the current screen size and video aspect ratio.
// Adjust video view size
val videoView = mViewHolder.mPlayScene.surfaceView
val videoParams = videoView.layoutParams as FrameLayout.LayoutParams
videoParams.width = displayAdapterResult.mVideoWidth
videoParams.height = displayAdapterResult.mVideoHeight
videoView.requestLayout()
// Adjust outer container size
mViewHolder.mPlayScene.setPlayViewHeight(displayAdapterResult.mLayoutHeight, displayAdapterResult.mLayoutWidth)A utility class DisplayMetricsUtil originally cached screen width/height, which caused stale values after folding. The new implementation adds a time‑based invalidation mechanism.
private static void refreshOnInvalid() {
final long time = SystemClock.elapsedRealtime();
final boolean isOverdue = (time - SCREEN_REFRESH_TIMESTAMP) > REFRESH_INTERVAL;
if (isOverdue || SCREEN_WIDTH_PIXELS <= 0 || SCREEN_HEIGHT_PIXELS <= 0) {
DisplayMetrics displayMetrics = getCurrentResources().getDisplayMetrics();
SCREEN_WIDTH_PIXELS = displayMetrics.widthPixels;
SCREEN_HEIGHT_PIXELS = displayMetrics.heightPixels;
SCREEN_REFRESH_TIMESTAMP = time;
}
}
public static int getScreenWidth() {
refreshOnInvalid();
return SCREEN_WIDTH_PIXELS;
}
public static int getScreenHeight() {
refreshOnInvalid();
return SCREEN_HEIGHT_PIXELS;
}The new utility can also be forced to invalidate when a configuration change is received:
public static void notifyOnConfigurationChanged(@NonNull Fragment fragment, @NonNull Configuration configuration) {
SCREEN_REFRESH_TIMESTAMP = 0L;
DisplayViewModel displayViewModel = ViewModelProviders.of(fragment).get(DisplayViewModel.class);
displayViewModel.notifyOnConfigurationChanged(configuration);
}Other Adaptation Schemes
Multi‑Window Mode
Android 7.0 introduced multi‑window support, allowing two apps to share the screen. While useful, it can split user attention and cause lifecycle issues on pre‑9.0 devices.
Enable it via manifest:
<application android:resizeableActivity="true">In‑App Split‑Screen Mode
Huawei’s parallel view solution lets a single app display two activities side‑by‑side, but it is vendor‑specific and requires substantial UI redesign.
Compatibility Mode
If the app cannot fully adapt, the system falls back to embedding the UI within the supported aspect‑ratio range.
Configure aspect ratios in the manifest (pre‑8.0):
<meta-data android:name="android.max_aspect" android:value="2.4"/>
<meta-data android:name="android.min_aspect" android:value="1.8"/>For 8.0+:
<activity android:name=".MainActivity" android:maxAspectRatio="2.4"/>Multi‑Display Support
Android 10+ allows activities to be launched on secondary displays. The app can query available displays via DisplayManager and launch activities on a chosen display using ActivityOptions .
DisplayManager mgr = (DisplayManager) this.getBaseContext().getSystemService(Context.DISPLAY_SERVICE);
Display[] displays = mgr.getDisplays();
// ... select a display and launch
ActivityOptions options = ActivityOptions.makeBasic();
options.launchDisplayId = targetDisplay.displayId;
startActivity(intent, options.toBundle());Testing Adaptation Effects
ADB Simulation
When a foldable device is unavailable, developers can simulate folding/unfolding by changing the device’s resolution with ADB commands.
# Set primary screen size
adb shell wm size 1148x2480
# Simulate unfolded state
adb shell wm size 2200x2480
# Reset
adb shell wm size resetEmulator
Android Studio 3.5+ provides foldable device profiles in the emulator, allowing visual testing of folding behavior.
Conclusion
Google continuously improves support for new screen form factors, from notches to foldables and multi‑display scenarios. While perfect adaptation is ideal, developers must balance effort with user base needs and choose reasonable strategies.
Thank you for reading!
Tencent Music Tech Team
Public account of Tencent Music's development team, focusing on technology sharing and communication.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.