在Android7.0中引入了類似PC上多窗口的支持,屏幕上能同時顯示多個,用戶在與另一個應用交互的同時可以繼續播放視頻。如果是用N Preview SDK構建應用,則可以配置應用的多窗口顯示方法。
一、多窗口預覽
1. 預覽圖如下:
2. 用戶切換到多窗口模式的方法:
- 若用戶打開 Overview 屏幕并長按 Activity 標題,則可以拖動該 Activity 至屏幕突出顯示的區域,使 Activity 進入多窗口模式。
- 若用戶長按 Overview 按鈕,設備上的當前 Activity 將進入多窗口模式,同時將打開 Overview 屏幕,用戶可在該屏幕中選擇要共享屏幕的另一個 Activity。
二、多窗口模式配置
在清單文件(AndroidManifest.xml)中可以對應用的Activit是否支持多窗口顯示以及顯示方式進行配置。
1. 配置是否支持多窗口:
在清單文件的 <activity> 或 <application> 節點中設置該屬性,啟用或禁用多窗口顯示:
android:resizeableActivity=["true" | "false"]
如果該屬性設置為 true,Activity 將支持多窗口模式。 如果此屬性設置為 false,Activity 將不支持多窗口模式,且用戶嘗試在多窗口模式下啟動 Activity,該 Activity 將全屏顯示。如果是用Android N SDK構建應用,但未對該屬性指定值,則該屬性的值默認設為 true。
2. 對多窗口顯示方式進行配置:
Android N 在清單文件的 <Activity> 節點下增加了一個 <layout> 標簽。該標簽支持一下幾種屬性:
android:defaultWidth //多窗口模式下Activity 的默認寬度
android:defaultHeight //多窗口模式下Activity 的默認高度
android:gravity //多窗口模式下Activity 的初始位置
android:minHeight //多窗口模式下Activity 的最小高度
android:minWidth //多窗口模式下Activity 的最小寬度
android:minimalWidth
已經被替換成android:minWidth
android:minimalHeight
已經被替換成android:minHeight
如果還是使用:android:minimalHeight
和android:minimalWidth
編譯不會通過。
例如:以下節點顯示了如何指定Activity在多窗口模式中顯示的大小、位置和最小尺寸:
<activity
android:name=".MyActivity"
android:resizeableActivity="true">
<layout
android:defaultHeight="500dp"
android:defaultWidth="600dp"
android:gravity="top|end"
android:minHeight="450dp"
android:minWidth="300dp" />
</activity>
3. 多窗口模式禁用的功能:
- 無法隱藏狀態欄
- 系統將忽略對 android:screenOrientation 屬性所作的更改
4. 多窗口模式下常用的方法:
- Activity.isInMultiWindowMode();
調用該方法以確認 Activity 是否處于多窗口模式。 - Activity.onMultiWindowModeChanged();
Activity 進入或退出多窗口模式時系統將調用此方法。 在 Activity 進入多窗口模式時,系統向該方法傳遞 true 值,在退出多窗口模式時,則傳遞 false 值。
5. 在多窗口模式中啟動新 Activity
如果當前應用處于多窗口模式,想要在該應用啟動的Activity顯示在當前 Activity 旁邊,則需要使用標志位:Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT 和ntent.FLAG_ACTIVITY_NEW_TASK
例如:
Intent intent = new Intent();
intent.setClass(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
啟動后兩個Activity處于分屏模式,如圖:
如果處于多窗口模式下,可以通過調用 ActivityOptions.setLaunchBounds() 指定新 Activity 的尺寸和屏幕位置,如果不處于多窗口模式則該方法無效。
示例代碼:
Rect rect = new Rect(0,400,800,1000);
ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchBounds(rect);
Intent intent = new Intent();
intent.setClass(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT|Intent.FLAG_ACTIVITY_NEW_TASK);
ActivityCompat.startActivity(this,intent,options.toBundle());
三、多窗口的生命周期
多窗口模式下Activity的生命周期并沒有改變,只是在切換到多窗口和退出多窗口模式時有所不同。在這兩種切換過程中Activity會被銷毀后重新創建,所以在這兩種模式下應該通過:onSaveInstanceState 和 onRestoreInstanceState 這兩個方法做好數據的保存和恢復。
如果在多窗口模式下播放視頻,應該在 onStop() 和 onStart() 這兩個方法中去暫停和繼續播放,這樣會有更好的用戶體驗。
四、多窗口模式下數據拖放
多窗口模式下的拖放,僅僅是數據的拖放,并不能將一個Activity的View拖放到另一個Activity。跨Activity拖放需要:View.DRAG_FLAG_GLOBAL 這個標志。
例如從MainActivity拖放一個按鈕中的數據到MyActivity中:
MainActivity:
btn = (Button) findViewById(R.id.my_button);
btn.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
ClipData data = ClipData.newPlainText(view.getClass().getName(), ((Button) view).getText());
View.DragShadowBuilder builder = newView.DragShadowBuilder(view);
view.startDragAndDrop(data, builder, view, View.DRAG_FLAG_GLOBAL);
return true;
}
});
MyActivity:
textView = (TextView) findViewById(R.id.text);
View parent = (View) textView.getParent();
parent.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DROP:
ClipData.Item item = event.getClipData().getItemAt(0);
textView.setText(item.getText());
break;
}
return true;
}
});
實現效果圖: