平板與手機支援
還記得上一章的內容嗎?解析度與多螢幕中我們是需用根據不同的螢幕來提供多種讓系統可選擇的資源,這樣你的App就能適用很多裝置了。然後有時候你應該想要進一步最佳化它們。例如平板
提供更多的空間,讓你的App能能顯示更多的資訊,但在手機上時可以會分幾個部分顯示,不會一次性全部顯示出來。大部分情況下平板和手機的體驗會有明顯的不同。
在android3.0上 ,android 引入了一套新的架構API,它允許我們更有效設計App,並更好的利用大螢幕。例如3.0新加入的Fragment類,這個類允許你對不同行為的UI組件分成獨立的部
分。然後你可以建立多屏裝置(例如2屏,3屏手機)的布局啦並使它們結合起來。android3.0還匯入了ActionBar這個類,它在螢幕上方提供一個專門的使用者介面,來識別APP並提供使用者操作
和導航。這種比較先進的技術,大家都很想用吧,不過裝置很難搞,我目前還只在國外的視頻中看到過3屏的手機,但我們可以在一個螢幕上分幾個面板也行的。
本章內容提供指導,在手機和平板上這兩種裝置上,它協助你建立一個獨特的並最佳化使用者體驗的App,並且使用fragments和action bar。
請記住看這一章之前,請看完解析度那兩章,它對你理解本章內容有重要的作用。該文章描述了一個使用者介面,它支援不同的螢幕尺寸和密度與靈活的布局和替代位元影像,並告訴你基本設計原則。
基本設計原則
下面是一些設計原則它能協助你建立一個在手機和平板中都能適用的App,並且最佳化使用者體驗。
- 基於fragments ,建立我們的activity:可重複使用的不同組合----多面板平板和單面板手機。在一個Acivity中一個 Fragment 代表一個行為或者一部分使用者介面。你可以認為
Fragment是一個Activity中的一種模組。有其自己的生命週期,並可以在其中添加或刪除而正在啟動並執行Activity。如果你沒有用過fragments,沒關係,我們會在android 架構學習中的第一
章講解,而且還有SDK中的例子。
- 使用ActionBar:它可以根據螢幕上的大小調整 action bar 的布局。
ActionBar是一個UI組件,它可以替代傳統的 title bar(是一種目前經常用的通知欄,因為ActionBar是一種比較新的技術,目前國內用的少)。預設的 action bar 在上方的左邊顯示我們的
App logo,然後是標題。右側則是可以訪問的選擇菜單。你可以從選項菜單開啟一個items(items可以理解為list或菜單中的一個項目)並直接開啟它。你也能添加有導航功能的action bar
作為標籤或者下拉式清單。直接點擊icon還會導航到home頁或者相當於一個back鍵的功能。
- 實現靈活布局:一個靈活的布局設計允許你的App能使用螢幕大小的變化。不是所有的平板和手機都是一樣的大小。你要根據平板和手機提供不同的fragment 組合,因為對於靈活調
整布局有很重要的作用。
注意: 請使用android3.0版本才有可用的API哦!
建立單面板和多面板布局用最有效方法來建立不同的使用者體驗 為平板和手機是建立具有不同的fragments組合布局,它會給你的使用者帶來非常棒的使用者體驗,你能為平板設計多面板布局,為手機設定單面板布局。 例如,在平板上一個新的App需要在左邊顯示一個文章列表,右邊則是文章的內容,並且點擊左邊的列表,右邊的內容會更新。在手機上這2個組件將被分別顯示。在fragment中我們有兩種 技術實踐這種設計:
- 多個fragments, 一個activity: 不管裝置的大小隻使用一個activity,在運行時決定是否結合(多面板)或者分開(單面板)。
- 多個fragments, 多個activity: 在平板上, 一個Activity中放置多個fragments;在手機上, 使用多個區分開來的activities分別控制每一個fragment. 例如, 當平板在的一個Activity中設計2個fragments, 使用同樣的activity在手機上的話,效果就會不一樣了。手機上執行當你需要切換fragments 時,就會啟動另一個Activity來放置第二個fragment。
你選擇的方法取決於你的設計和個人喜好. 第一個選項(1個activity; 多個fragments) 你需要在運行時確定螢幕的大小並動態添加每一個fragment ,而非用xml來描述一個布局,因為如果它 在XML聲明了,你就不能刪除那一個fragments了。我們使用選項一的時候,在fragments每一次改變時,可能我們還需要更新action bar。這些因素可能不會影響我們的設計,所以使用選 項一效果還是很好的(特別是你有動態添加刪除fragments的需求的情況)。動態東西代碼上會複雜一些,你需要權衡一下!! 本指南重點介紹了第二個選項,在其中顯示在單獨的活動時,一個小螢幕的每一個片段。使用這項技術,意味著你可以使用替代的布局檔案,為不同的螢幕大小定義不同的fragments組合, 保持fragments代碼模組化,簡化action bar的管理,讓系統在手機上處理所有回棧工作。
下面的圖說明手機和平板下fragments的工作原理:
圖1. 我們可以吧這種設計看成一種設計模式,左邊的是組合關係,它吧所有frag組合到一個act中,右邊則是彙總,每一個Act中都有一個frag 他們只有彙總到一起才完成一個完整的功能
就像雁群和大雁(彙總), 大雁和翅膀(組合)。
系統應用於不同的main.xml布局檔案取決於螢幕的大小:
手機上的res/layout/main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- "Fragment A" -->
<fragment class="com.example.android.TitlesFragment"
android:id="@+id/list_frag"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
平板上的res/layout-large
/main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/frags">
<!-- "Fragment A" -->
<fragment class="com.example.android.TitlesFragment"
android:id="@+id/list_frag"
android:layout_width="@dimen/titles_size"
android:layout_height="match_parent"/>
<!-- "Fragment B" -->
<fragment class="com.example.android.DetailsFragment"
android:id="@+id/details_frag"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
注意: 大家目前可能看不懂xml檔案,因為還沒開始寫過代碼。沒關係這裡主要是體現平板和手機上布局的不同之處。需要重點說明的是,不要看它在xml設定了布局,其實他還是用代碼寫的布局,com.example.android.**就是很明顯的標誌。
還有2個xml中是放在不同的檔案夾下的, 後者有large的區別哦!!另外為什麼平板中的main.xml會多出一個Fragment B而手機中卻沒有呢?因為平板需要同時在一個activity中顯示2個,而手機只需要顯示一個A就行了,這依賴於裝置,而且在下面的代碼中也能用Fragment B是否為空白來判定裝置是手機還是平板
使用者選擇一個item時,Fragment B是怎樣被響應的:
- 如果Fragment B 在Layout裡,Activity A會通知iFragment B來更新它自己。
- 如果Fragment B 不在Layout裡, Activity A 會啟動 Activity B。
為了實現這個模式,我們需要高度劃分好。以下是兩條準則:
- 不要從另一個fragment 直接的操作一個fragment 。
- 保留所有涉及內容的代碼在一個fragment裡,而不是放到activity中。
避免直接的從一個fragment 調用另一個fragment,應該在每一個fragment類中定義一個回調介面<在java中介面是深層物件導向必須掌握的知識(個人認為應該是面向抽象編程),不熟的同
學需要補習以下哦>。這裡介面的用途是用來傳遞事件到activity中,當 activity 收到一個由事件引發的回調,那麼這個activity 就會響應並適當的處理。
例如Activity A處理item的選擇,取決於是否它使用平板或手機布局,代碼如下:
public class MainActivity extends Activity implements TitlesFragment.OnItemSelectedListener {
...
/** 由於當前MainActivity(Fragment A) 實現了TitlesFragment.OnItemSelectedListener介面
所以它必須實現onItemSelected(int position)方法,這裡是由於選擇了Fragment A中的item然後此方法就被執行了
*/
public void onItemSelected(int position) {
DisplayFragment displayFrag = (DisplayFragment) getFragmentManager()
.findFragmentById(R.id.display_frag);
if (displayFrag == null) {
// 用來顯示的Fragment (Fragment B)
// 如果displayFrag ==null了就是說明這是在手機上的布局,那麼在手機上我們該如果操作呢?
// 那就是使用intent 傳遞一個資料並 啟動DisplayActivity(Fragment B)
Intent intent = new Intent(this, DisplayActivity.class);
intent.putExtra("position", position);
startActivity(intent);
} else {
// 否則就是在平板的上的布局
// 那麼我們直接調用displayFrag.updateContent(position);來更新即可
displayFrag.updateContent(position);
}
}
當Activity B(請記住B是用來顯示的,A是用來選擇item的)啟動時候,它會讀取資料,這個資料是在Activity A中使用Intent傳遞過來的。關於這種技術在sdk下的sample下有個例子,
實戰篇我們在"實戰":)
使用 Action Bar
不管是在平板還是手機上Action Bar是一個重要的UI組件。儘管Action Bar很有用但它並不複雜。反正第二大篇我們會講的。下面的內容主要講的是關於Action Bar和螢幕大小之間的關係和適應情況。當我們建立一個Action Bar時,下面這一些最好你們稍微看一下,對你是有協助的:
- 當設定一個菜單item作為一個action item時,請避免使用 "always"這個值。在你的菜單資源(屬於xml檔案)裡,如果你想要菜單item出現在action bar下中,請使用
android:showAsAction
="ifRoom
"屬性。但是當動作條view沒有為菜單提供預設的action時,你還是可能需要“always”的。這種情況還是很少見的。而且如果action item太多,這樣會很雜亂,並且會導致標題列或導航項目重疊。這樣根本不好選擇!簡潔很重要。
- 當添加一個action item到 action bar時,請使用一個文本標題和一個icon,例如
showAsAction="ifRoom|withText"
,如果標題太長,那使用一個icon就OK了
- 在action item中盡量一直提供一個標題,如果你沒有開啟
"withText"
,就使用toast(android裡的一個用來短暫顯示內容的控制項),這樣使用者會看到一個短暫的提示,從而進行些什麼操作之類的,請千萬不要忽視這種細節問題
- 就算能使用自訂的導航模式,也請避免使用。最好使用內建嵌入或者下拉模式,這樣系統能根據不同的螢幕自動適應。例如當2個標籤和其他action item在一起時,如果寬度太窄 ,那麼標籤就會出現在action bar的下面。如果你非要在 action bar中使用自訂的導航模式或其他自訂的view的話,請在不同的螢幕下徹底的測試它們。
下面有一張圖, 讓我們看看平板和手機中的action bar 是怎樣適應螢幕的。
圖2. 你可以看到attach help setting 這三項在平板中是在上面,而在手機中則是出現在下面並且類似於菜單中的一個item了,這就是它們明顯的區別。其實看久了你會不會發現平板的大氣。在手機上開發的時候,建議介面以簡約為主。
使用split action bar
當你的App在android4.0(或更高)運行時,關於action bar有一個額外的模式可用,那就是split action bar。當你開啟 split action bar,模式並在豎屏情況下,一個分隔的bar會出現在螢幕的底部用來顯示所有的action items。
開啟 split action bar, 需要添加 uiOptions="splitActionBarWhenNarrow"
到manifest 中的 <activity>
or <application>
節點。讓我們來看一吧:
圖3.
注意: 請記住在android 4.0下才可使用“uiOptions
”。低版本系統會忽視這個屬性。