Android開發學習之路-Android N新特性-多窗口模式


我們都知道,在最新的Android N系統中,加入了一個新的功能,就是多窗口模式。多窗口模式允許我們在屏幕上顯示兩個窗口,每個窗口顯示的內容不同,也就是說,我們可以一遍看電視劇,一邊聊微信。

這里我們通過官方提供的一個Demo來了解一下,作為開發者,怎么給我們的App也適配多窗口模式。

這里給出代碼github地址,需要的話可以clone下來邊看邊了解:

https://github.com/googlecodelabs/getting-ready-for-android-n

 

根據指導文檔這里分為幾個部分:

1. 多窗口模式的開關

2. 多窗口模式適配

3. 多窗口模式中打開新的窗口處理

 

我們一個一個來了解下:

1. 多窗口模式的開關

默認情況下,我們的App都是允許多窗口的,但是,如果沒有進行屬性的設置,會系統會拋出一個提示這個應用可能不支持多窗口模式

那么,如果我們的應用要支持這個模式並且不讓這個消息彈出來,要怎么做呢?

很簡單,只需要在Activity聲明的時候加入一個屬性resizeableActivity,並且設置其值為true即可

<activity
    android:name=".MainActivity"
    android:resizeableActivity="true">
    <intent-filter>
       <action android:name="android.intent.action.MAIN"/>
    <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>

這個屬性的設置會導致三種情況:

① 如果不聲明這個屬性,那么默認允許進入多窗口模式,但是會有上面圖片的提示(第一次運行的時候)

② 如果聲明了這個屬性,並設置值為true,那么允許進入多窗口模式,並且不會提示

③ 如果聲明了這個屬性,並設置值為false,那么不允許進入多窗口模式,只允許全屏顯示

 

2. 多窗口模式的適配

當我們允許App進入多窗口模式之后,App只能占據屏幕的一部分,假設我們的App運行的界面如下(官方Demo):

可以看到,在App的上半部分是一個藍色的圖片背景,在上面顯示了當前的天氣狀況,但是如果我們不進行適應,那么進入了多窗口模式之后,這個部分的內容就會幾乎占滿整個窗口,這個時候我們就需要進行一下適配,當進入多窗口模式之后更換掉這一個布局,將內容進行重新排版,以便顯示更多的內容。

默認情況下的布局:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="wrap_content"
 4     android:gravity="center_vertical"
 5     android:minHeight="?android:attr/listPreferredItemHeight"
 6     android:orientation="horizontal"
 7     android:background="@drawable/today_touch_selector">
 8 
 9     <LinearLayout
10         android:layout_height="wrap_content"
11         android:layout_width="0dp"
12         android:layout_weight="7"
13         android:layout_marginTop="16dp"
14         android:layout_marginBottom="16dp"
15         android:layout_marginLeft="60dp"
16         android:orientation="vertical">
17 
18         <TextView
19             android:id="@+id/list_item_date_textview"
20             android:layout_width="match_parent"
21             android:layout_height="wrap_content"
22             android:textAppearance="?android:textAppearanceLarge"
23             android:fontFamily="sans-serif-condensed"
24             android:textColor="@color/white" />
25 
26         <TextView
27             android:id="@+id/list_item_high_textview"
28             android:layout_width="match_parent"
29             android:layout_height="wrap_content"
30             android:textSize="72sp"
31             android:fontFamily="sans-serif-light"
32             android:textColor="@color/white" />
33 
34         <TextView
35             android:id="@+id/list_item_low_textview"
36             android:layout_width="match_parent"
37             android:layout_height="wrap_content"
38             android:textColor="@color/white"
39             android:textSize="36sp"
40             android:layout_marginLeft="8dp"/>
41     </LinearLayout>
42 
43     <LinearLayout
44         android:layout_height="wrap_content"
45         android:layout_width="0dp"
46         android:layout_weight="5"
47         android:layout_marginRight="16dp"
48         android:orientation="vertical"
49         android:gravity="center_horizontal|bottom">
50 
51         <ImageView
52             android:id="@+id/list_item_icon"
53             android:layout_width="wrap_content"
54             android:layout_height="wrap_content"
55             android:layout_gravity="center_horizontal"/>
56 
57         <TextView
58             android:id="@+id/list_item_forecast_textview"
59             android:layout_width="wrap_content"
60             android:layout_height="wrap_content"
61             android:fontFamily="sans-serif-condensed"
62             android:layout_gravity="center_horizontal"
63             android:textAppearance="?android:textAppearanceLarge"
64             android:textColor="@color/white"/>
65     </LinearLayout>

這里主要看到,根布局中設置了背景圖,這個圖片就是那個我們看到藍色的那一張,里面定義了一些TextView來顯示信息,定義了一個ImageView來顯示天氣的圖標,簡單了解下布局即可。

因為這里用到Fragment,可能直接看工程不會很清晰,我們打開res下的values-sw400dp,然后打開里面的refs.xml文件,內容如下:

<resources>
    <item type="layout" name="fragment_detail">@layout/fragment_detail_wide</item>
    <item type="layout" name="list_item_forecast_today">@layout/list_item_forecast_today_big</item>
</resources>

我們將光標移動到第二個Item的name屬性的值中,然后按下Alt+F7找到項目中用到這個value的地方:

可以看到,只有一個地方使用了這個value,我們點進去可以看到,這個布局其實是被用在了一個CursorAdapter中,這里應該就知道了,這個布局是被當作一個ListView的頭部來使用。

我們先不管工程是如何實現的,我們只需要知道這個布局會被用在界面中的ListView中的頭部中就可以了。這個時候我們再看看這個folder的文件名values-sw400dp,sw400dp就表明了這個value是在屏幕最短邊大於等於400dp的時候生效(前提是有其他不同的value文件夾)。

因為在多窗口模式的情況下,每個窗口分的大小是允許用戶控制的(可以通過中間的滑動來改變兩個窗口的大小),而當用戶將滑塊向上滑動,有可能會會導致最短邊小於400dp,因此,我們可以在工程的res下創建一個更小的values文件名為values-sw220dp,接着再創建一個布局文件(里面的控件id必須和上面的布局一致,這里Demo中已經給出了一個布局,名字是list_item_forecast),接着在values-sw220dp下創建一個refs.xml的文件,文件內容如下:

<resources>
    <item type="layout" name="list_item_forecast_today">@layout/list_item_forecast</item>
</resources>

運行的效果如下所示,可以看到,當屏幕最短邊大於220dp而小於400dp的時候,會顯示如右圖的布局:

  

這里還要注意一個問題,如果我們按照上面定義的220dp來命名,那么如果屏幕被繼續向上拉,會導致最小邊小於220dp,這個時候又會恢復到左邊的這個布局,這里解決辦法是把220dp設置的更小(如100dp)即可。

這里補充一下效果:

 

3. 在多窗口中打開一個Activity

在官方的Demo中,可以通過右上角的菜單中的“Map Location”來打開地圖App,這個時候如果不加以設置,地圖App會在當前的這個小窗口中打開。

那么我們可不可以讓系統在下面的這個窗口打開呢?因為考慮到用戶可以不用跳出我們的App而對地圖App進行操作,谷歌官方也是提供了這個功能,而且比較簡單。

我們找到ForecastFragment.class這個類,定位到206行,代碼如下:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(geoLocation);

很明顯這里是要打開一個Activity,接着我們只需要給這個Intent設置一個標簽,完整代碼如下:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(geoLocation);
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);

這個時候,我們再此運行App並打開地圖App,會發現,地圖App會在另一個窗口中被打開。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM