Android 16系统源码_分屏模式(一)触发分屏模式
前言
从 Android 7.0 开始,Google 推出了一个名为“多窗口模式”的新功能,允许在设备屏幕上同时显示多个应用,多窗口模式允许多个应用同时共享同一屏幕,多窗口模式(Multi Window Supports)目前支持以下三种配置:
本系列文章我们主要来分析一下分屏模式相关的知识点。
分屏模式案例
资源配置文件
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- 关键配置:启用分屏并处理配置变更 -->
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask"
android:resizeableActivity="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 第二个Activity用于分屏测试 -->
<activity android:name=".SecondActivity" />
</application>
</manifest>
布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFF00"
android:gravity="center"
android:padding="100dp"
android:text="主页处于全屏"
android:textSize="30sp"
android:textStyle="bold" />
<Button
android:id="@+id/btn_open_second"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="打开第二个页面" />
</LinearLayout>
布局文件activity_second.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFF00"
android:gravity="center"
android:padding="100dp"
android:text="第二个页面"
android:textSize="30sp"
android:textStyle="bold" />
</LinearLayout>
项目源码
MainActivity.java
public class MainActivity extends Activity {
private static final String TAG = "TestMainActivity";
private TextView mTvStatus;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate: ");
setContentView(R.layout.activity_main);
mTvStatus = findViewById(R.id.tv_status);
findViewById(R.id.btn_open_second).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
// 恢复输入内容
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.i(TAG, "onRestoreInstanceState: ");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart: ");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume: ");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause: ");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop: ");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy: ");
}
// 监听分屏模式变化
@Override
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
super.onMultiWindowModeChanged(isInMultiWindowMode);
Log.i(TAG, "onMultiWindowModeChanged: isInMultiWindowMode = " + isInMultiWindowMode);
mTvStatus.setText(isInMultiWindowMode ? "当前处于分屏模式" : "当前处于全屏模式");
}
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG, "onConfigurationChanged: ");
}
}
SecondActivity.java
public class SecondActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
从最近任务触发分屏模式
打开MainActivity,然后进入最近任务触发分屏,可以成功进入分屏模式,具体可以参考下图。
以分屏模式打开一个新的Activity
点击MainActivity的页面的按钮,以分屏方式打开SecondActivity,也可以进入分屏模式。
分屏模式的适配
配置AndroidManifest.xml
若项目的targetSDKVersion 大于等于24,那么可以在AndroidManifest.xml 文件的Application 或Activity 节点通过设置android:resizeableActivity=[“true” | “false”] 来控制整个 APP 或某个 Activity 是否支持分屏。该属性的默认值是true ,也就是说,如果不设置该属性,在支持分屏的设备上,默认是可以分屏的。
若项目的targetSDKVersion 小于24,那么运行在支持分屏的设备上,默认可以分屏。这时如果需要禁止分屏,需要在AndroidManifest.xml 文件的Application 或Activity 节点设置android:screenOrientation 属性来控制整个 APP 或 某个 Activity 的屏幕方向,从而控制整个 APP 或某个 Activity 禁止分屏。
以分屏模式打开新的Activity
如果 APP 在分屏模式下打开 Activity 时,为 Intent 设置了Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT 和Intent.FLAG_ACTIVITY_NEW_TASK 标志,那么新打开的 Activity 将显示在当前 APP 的另一侧。例如下面的代码:
Intent intent = new Intent(this, NewActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
分屏模式的监听
能不能在代码中监听 APP 是否进入分屏模式呢?答案当然是能。由于 APP 在分屏模式发生改变时会执行onMultiWindowModeChanged 方法,因此我们在 Activity 中重写这个方法,通过这个方法就可以实现分屏的监听了。
@Override
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
super.onMultiWindowModeChanged(isInMultiWindowMode);
// 判断当前是否为分屏模式
if (isInMultiWindowMode) {
// 已进入分屏模式
} else {
// 未进入分屏模式
}
}
防止UI自动重建
默认情况下当Activity发生分屏和全屏场景切换的时候,进入分屏模式时,onCreate方法会被重新调用导致UI重建。为了防止这种情况,可以在AndroidManifest.xml 的Activity 节点设置以下属性:
android:configChanges=“screenSize|smallestScreenSize|screenLayout|orientation”
设置了这个属性,在进入分屏模式时,onCreate方法就不会会被重新调用,Activity也不会重建了。
分屏模式下的生命周期
configChanges未添加防重建属性
- 进入分屏模式时,Activity 的生命周期:
onPause()- onStop()- onSaveInstanceState()- onDestroy()- onCreate()- onStart()- onRestoreInstanceState()- onResume()
- 退出分屏模式时,Activity 的生命周期:
onPause()- onStop()- onSaveInstanceState()- onDestroy()- onCreate()- onStart()- onRestoreInstanceState()- onResume()
configChanges添加防重建属性
- 进入分屏模式时,Activity 的生命周期:
onPause()- onMultiWindowModeChanged()- onConfigurationChanged()- onResume()
- 退出分屏模式时,Activity 的生命周期:
onMultiWindowModeChanged()- onConfigurationChanged()
💡 技术无价,赞赏随心
写文不易,如果本文帮你避开了“八小时踩坑”,或者让你直呼“学到了!”
欢迎扫码赞赏,让我知道这篇内容值得!
更多推荐


所有评论(0)