鍍金池/ 教程/ Android/ 支持不同的屏幕大小
檢測(cè)常用的手勢(shì)
優(yōu)化layout的層級(jí)
用戶輸入
管理應(yīng)用的內(nèi)存
聯(lián)系人信息
開發(fā)輔助程序
Android多媒體
添加語音功能
顯示位置地址
提供向下與橫向?qū)Ш?/span>
支持游戲控制器
訪問可穿戴數(shù)據(jù)層
處理多點(diǎn)觸控手勢(shì)
全屏沉浸式應(yīng)用
為多線程創(chuàng)建管理器
數(shù)據(jù)保存
Intent的發(fā)送
更新Notification
優(yōu)化下載以高效地訪問網(wǎng)絡(luò)
打印
打包可穿戴應(yīng)用
接收從其他App傳送來的數(shù)據(jù)
發(fā)送與接收消息
建立靈活動(dòng)態(tài)的UI
處理鍵盤輸入
Building a Work Policy Controller
建立測(cè)試環(huán)境
創(chuàng)建表盤
分享文件
顯示Notification進(jìn)度
實(shí)現(xiàn)自適應(yīng)UI流(Flows)
使用設(shè)備管理策略增強(qiáng)安全性
使用能感知版本的組件
執(zhí)行網(wǎng)絡(luò)操作
建立文件分享
添加移動(dòng)
更新你的Security Provider來對(duì)抗SSL漏洞利用
支持鍵盤導(dǎo)航
創(chuàng)建和監(jiān)視地理圍欄
發(fā)送并同步數(shù)據(jù)
使用BigView樣式
無線連接設(shè)備
提供向上導(dǎo)航與歷史導(dǎo)航
最小化定期更新造成的影響
實(shí)現(xiàn)向下的導(dǎo)航
支持不同的屏幕大小
Android 可穿戴應(yīng)用
添加動(dòng)畫
顯示聯(lián)系人頭像
使用OpenGL ES顯示圖像
處理輸入法可見性
分享文件
保持設(shè)備喚醒
淡化系統(tǒng)Bar
使用NFC分享文件
保存到Preference
Android聯(lián)系人信息與位置信息
創(chuàng)建標(biāo)準(zhǔn)的網(wǎng)絡(luò)請(qǐng)求
使用Drawables
管理Bitmap的內(nèi)存使用
管理Activity的生命周期
按需加載視圖
傳輸資源
為可穿戴設(shè)備創(chuàng)建自定義UI
在一個(gè)線程中執(zhí)行一段特定的代碼
性能優(yōu)化
隱藏導(dǎo)航欄
創(chuàng)建目錄瀏覽器
為多種大小的屏幕進(jìn)行規(guī)劃
View間漸變
使用觸摸手勢(shì)
高效加載大圖
使用CursorLoader在后臺(tái)加載數(shù)據(jù)
創(chuàng)建抽屜式導(dǎo)航(navigation drawer)
管理音頻焦點(diǎn)
創(chuàng)建后臺(tái)服務(wù)
創(chuàng)建功能測(cè)試
創(chuàng)建使用Material Design的應(yīng)用
停止與重啟Activity
添加一個(gè)簡(jiǎn)便的分享功能
啟動(dòng)Activity時(shí)保留導(dǎo)航
TV應(yīng)用清單
創(chuàng)建向后兼容的UI
?# 優(yōu)化自定義View
創(chuàng)建單元測(cè)試
在UI上顯示Bitmap
建立OpenGL ES的環(huán)境
構(gòu)建表盤服務(wù)
JNI Tips
建立搜索界面
實(shí)現(xiàn)自定義View的繪制
使用HTTPS與SSL
按需操控BroadcastReceiver
分享簡(jiǎn)單的數(shù)據(jù)
繪制形狀
Android位置信息
創(chuàng)建并運(yùn)行可穿戴應(yīng)用
執(zhí)行 Sync Adpater
獲取最后可知位置
創(chuàng)建 Android 項(xiàng)目
實(shí)現(xiàn)高效的導(dǎo)航
退出全屏的Activity
創(chuàng)建Card
兼容音頻輸出設(shè)備
同步數(shù)據(jù)單元
傳輸數(shù)據(jù)時(shí)避免消耗大量電量
保存到文件
緩存Bitmap
提供配置 Activity
調(diào)度重復(fù)的鬧鐘
實(shí)現(xiàn)輔助功能
重復(fù)的下載是冗余的
隱藏狀態(tài)欄
實(shí)現(xiàn)自定義的網(wǎng)絡(luò)請(qǐng)求
規(guī)劃界面和他們之間的關(guān)系
使用Sync Adapter傳輸數(shù)據(jù)
TV應(yīng)用內(nèi)搜索
響應(yīng)觸摸事件
使用Google Cloud Messaging(已廢棄)
控制相機(jī)
Android網(wǎng)絡(luò)連接與云服務(wù)
請(qǐng)求分享一個(gè)文件
處理TV硬件
響應(yīng)UI可見性的變化
使用網(wǎng)絡(luò)服務(wù)發(fā)現(xiàn)
指定輸入法類型
優(yōu)化電池壽命
創(chuàng)建TV應(yīng)用
獲取聯(lián)系人列表
拖拽與縮放
啟動(dòng)與停止線程池中的線程
創(chuàng)建 Sync Adpater
使用 WiFi P2P 服務(wù)發(fā)現(xiàn)
開始使用Material Design
代理至新的APIs
使用include標(biāo)簽重用layouts
使得View可交互
高效顯示Bitmap
創(chuàng)建企業(yè)級(jí)應(yīng)用
Fragments之間的交互
創(chuàng)建與執(zhí)行測(cè)試用例
綜合:設(shè)計(jì)我們的樣例 App
繪制表盤
建立簡(jiǎn)單的用戶界面
自定義動(dòng)畫
開發(fā)輔助服務(wù)
避免出現(xiàn)程序無響應(yīng)ANR(Keeping Your App Responsive)
使用ViewPager實(shí)現(xiàn)屏幕滑動(dòng)
設(shè)計(jì)高效的導(dǎo)航
Android分享操作(Building Apps with Content Sharing)
提供向后的導(dǎo)航
保持向下兼容
創(chuàng)建TV播放應(yīng)用
縮放View
使用 WiFi 建立 P2P 連接
Android后臺(tái)任務(wù)
連接到網(wǎng)絡(luò)
為 Notification 添加頁面
使TV應(yīng)用是可被搜索的
添加Action Bar
使用Material的主題
啟動(dòng)另一個(gè)Activity
顯示正在播放卡片
適配不同的系統(tǒng)版本
輕松錄制視頻
創(chuàng)建可穿戴的應(yīng)用
創(chuàng)建自定義的布局
重新創(chuàng)建Activity
使用CursorLoader執(zhí)行查詢?nèi)蝿?wù)
使用舊的APIs實(shí)現(xiàn)新API的效果
使用備份API
安全要點(diǎn)
Android入門基礎(chǔ):從這里開始
保存并搜索數(shù)據(jù)
根據(jù)網(wǎng)絡(luò)連接類型來調(diào)整下載模式
使用Tabs創(chuàng)建Swipe視圖
SMP(Symmetric Multi-Processor) Primer for Android
解析 XML 數(shù)據(jù)
使用 Volley 傳輸網(wǎng)絡(luò)數(shù)據(jù)
建立ActionBar
Android交互設(shè)計(jì)
使用Intent修改聯(lián)系人信息
增加搜索功能
輕松拍攝照片
定義形狀
測(cè)試你的Activity
在 Notifcation 中接收語音輸入
與其他應(yīng)用的交互
管理系統(tǒng)UI
追蹤手勢(shì)移動(dòng)
Android界面設(shè)計(jì)
執(zhí)行 Android 程序
顯示確認(rèn)界面
創(chuàng)建Lists與Cards
打印HTML文檔
創(chuàng)建TV應(yīng)用
為多屏幕設(shè)計(jì)
定義Shadows與Clipping視圖
使用Fragment建立動(dòng)態(tài)UI
接收Activity返回的結(jié)果
布局變更動(dòng)畫
定位常見的問題
自定義ActionBar的風(fēng)格
定義Layouts
發(fā)送簡(jiǎn)單的網(wǎng)絡(luò)請(qǐng)求
啟動(dòng)與銷毀Activity
與UI線程通信
非UI線程處理Bitmap
創(chuàng)建TV布局
提升Layout的性能
報(bào)告任務(wù)執(zhí)行狀態(tài)
判斷并監(jiān)測(cè)網(wǎng)絡(luò)連接狀態(tài)
兼容不同的設(shè)備
處理按鍵動(dòng)作
優(yōu)化性能和電池使用時(shí)間
給其他App發(fā)送簡(jiǎn)單的數(shù)據(jù)
Implementing App Restrictions
向后臺(tái)服務(wù)發(fā)送任務(wù)請(qǐng)求
展示Card翻轉(zhuǎn)動(dòng)畫
管理ViewGroup中的觸摸事件
兼容不同的屏幕密度
通過藍(lán)牙進(jìn)行調(diào)試
為可穿戴設(shè)備創(chuàng)建Notification
控制音量與音頻播放
獲取聯(lián)系人詳情
在表盤上顯示信息
提供向上的導(dǎo)航
滾動(dòng)手勢(shì)動(dòng)畫
幫助用戶在TV上找到內(nèi)容
創(chuàng)建TV導(dǎo)航
為索引指定App內(nèi)容
ActionBar的覆蓋疊加
Android Wear 上的位置檢測(cè)
保護(hù)安全與隱私的最佳策略
Ensuring Compatibility with Managed Profiles
解決云同步的保存沖突
獲取位置更新
創(chuàng)建List
測(cè)試程序
管理網(wǎng)絡(luò)的使用情況
為App內(nèi)容開啟深度鏈接
推薦TV內(nèi)容
建立一個(gè)Notification
管理音頻播放
設(shè)計(jì)表盤
拍照
處理控制器輸入動(dòng)作
判斷并監(jiān)測(cè)設(shè)備的底座狀態(tài)與類型
處理查詢的結(jié)果
保存到數(shù)據(jù)庫(kù)
支持多個(gè)游戲控制器
創(chuàng)建 Stub Content Provider
使得ListView滑動(dòng)順暢
處理數(shù)據(jù)層的事件
創(chuàng)建TV應(yīng)用的第一步
使得你的App內(nèi)容可被Google搜索
將 Notification 放成一疊
創(chuàng)建 Stub 授權(quán)器
暫停與恢復(fù)Activity
管理設(shè)備的喚醒狀態(tài)
Android圖像與動(dòng)畫
打印照片
云同步
創(chuàng)建TV直播應(yīng)用
為Notification賦加可穿戴特性
提供一個(gè)Card視圖
建立請(qǐng)求隊(duì)列(RequestQueue)
適配不同的語言
創(chuàng)建詳情頁
測(cè)試UI組件
接收其他設(shè)備的文件
創(chuàng)建自定義View
建立第一個(gè)App
創(chuàng)建2D Picker
監(jiān)測(cè)電池的電量與充電狀態(tài)
打印自定義文檔
抽象出新的APIs
通知提示用戶
獲取文件信息
運(yùn)用投影與相機(jī)視角
在IntentService中執(zhí)行后臺(tái)任務(wù)
多線程操作
創(chuàng)建一個(gè)Fragment
添加Action按鈕
在不同的 Android 系統(tǒng)版本支持控制器
維護(hù)兼容性
發(fā)送文件給其他設(shè)備
創(chuàng)建TV游戲應(yīng)用
創(chuàng)建自定義的View類
代碼性能優(yōu)化建議
Intent過濾
適配不同的屏幕

支持不同的屏幕大小

編寫:riverfeng - 原文:http://developer.android.com/training/multiscreen/screensizes.html

這節(jié)課教你如何通過以下幾種方式支持多屏幕:

1、確保你的布局能自適應(yīng)屏幕

2、根據(jù)你的屏幕配置提供合適的UI布局

3、確保正確的布局適合正確的屏幕。

4、提供縮放正確的位圖(bitmap)

使用“wrap_content”和“match_parent”

為了確保你的布局能靈活的適應(yīng)不同的屏幕尺寸,針對(duì)一些view組件,你應(yīng)該使用wrap_content和match_parent來設(shè)置他們的寬和高。如果你使用了wrap_content,view的寬和高會(huì)被設(shè)置為該view所包含的內(nèi)容的大小值。如果是match_parent(在API 8之前是fill_parent)則會(huì)匹配該組件的父控件的大小。

通過使用wrap_content和match_parent尺寸值代替硬編碼的尺寸,你的視圖將分別只使用控件所需要的空間或者被拓展以填充所有有效的空間。比如:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout android:layout_width="match_parent"
                  android:id="@+id/linearLayout1"
                  android:gravity="center"
                  android:layout_height="50dp">
        <ImageView android:id="@+id/imageView1"
                   android:layout_height="wrap_content"
                   android:layout_width="wrap_content"
                   android:src="@drawable/logo"
                   android:paddingRight="30dp"
                   android:layout_gravity="left"
                   android:layout_weight="0" />
        <View android:layout_height="wrap_content"
              android:id="@+id/view1"
              android:layout_width="wrap_content"
              android:layout_weight="1" />
        <Button android:id="@+id/categorybutton"
                android:background="@drawable/button_bg"
                android:layout_height="match_parent"
                android:layout_weight="0"
                android:layout_width="120dp"
                style="@style/CategoryButtonStyle"/>
    </LinearLayout>

    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>

注意上面的例子使用wrap_content和match_parent來指定組件尺寸而不是使用固定的尺寸。這樣就能使你的布局正確的適配不同的屏幕尺寸和屏幕方向(這里的配置主要是指屏幕的橫豎屏切換)。

例如,下圖演示的就是該布局在豎屏和橫屏模式下的效果,注意組件的尺寸是自動(dòng)適應(yīng)寬和高的。

http://wiki.jikexueyuan.com/project/android-training-geek/images/layout-hvga.png" alt="" />

圖1:News Reader示例app(左邊豎屏,右邊橫屏)。

使用相對(duì)布局(RelativeLayout)

你可以使用LinearLayout以及wrap_content和match_parent組合來構(gòu)建復(fù)雜的布局,但是LinearLayout卻不允許你精準(zhǔn)的控制它子view的關(guān)系,子view在LinearLayout中只能簡(jiǎn)單一個(gè)接一個(gè)的排成行。如果你需要你的子view不只是簡(jiǎn)簡(jiǎn)單單的排成行的排列,更好的方法是使用RelativeLayout,它允許你指定你布局中控件與控件之間的關(guān)系,比如,你可以指定一個(gè)子view在左邊,另一個(gè)則在屏幕的右邊。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/label"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Type here:"/>
    <EditText
        android:id="@+id/entry"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/label"/>
    <Button
        android:id="@+id/ok"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/entry"
        android:layout_alignParentRight="true"
        android:layout_marginLeft="10dp"
        android:text="OK" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/ok"
        android:layout_alignTop="@id/ok"
        android:text="Cancel" />
</RelativeLayout>

http://wiki.jikexueyuan.com/project/android-training-geek/images/relativelayout1.png" alt="" />

圖2:QVGA(小尺寸屏幕)屏幕下截圖

http://wiki.jikexueyuan.com/project/android-training-geek/images/relativelayout2.png" alt="" />

圖3:WSVGA(大尺寸屏幕)屏幕下截圖

注意:盡管組件的尺寸發(fā)生了變化,但是它的子view之間的空間關(guān)系還是通過RelativeLayout.LayoutParams已經(jīng)指定好了。

使用尺寸限定詞

(譯者注:這里的限定詞主要是指在編寫布局文件時(shí),將布局文件放在加上類似large,sw600dp等這樣限定詞的文件夾中,以此來告訴系統(tǒng)根據(jù)屏幕選擇對(duì)應(yīng)的布局文件,比如下面例子的layout-large文件夾)

從上一節(jié)的學(xué)習(xí)里程中,我們知道如何編寫靈活的布局或者相對(duì)布局,它們都能通過拉伸或者填充控件來適應(yīng)不同的屏幕,但是它們卻不能為每個(gè)不同屏幕尺寸提供最好的用戶體驗(yàn)。因此,你的應(yīng)用不應(yīng)該只是實(shí)現(xiàn)靈活的布局,同時(shí)也應(yīng)該為不同的屏幕配置提供幾種不同的布局方式。你可以通過配置限定(configuration qualifiers)來做這件事情,它能在運(yùn)行時(shí)根據(jù)你當(dāng)前設(shè)備的配置(比如不同的屏幕尺寸設(shè)計(jì)了不同的布局)來選擇合適的布局資源。

比如,很多應(yīng)用都為大屏幕實(shí)現(xiàn)了“兩個(gè)窗格”模式(應(yīng)用可能在一個(gè)窗格中實(shí)現(xiàn)一個(gè)list的item,另外一個(gè)則實(shí)現(xiàn)list的content),平板和電視都是大到能在一個(gè)屏幕上適應(yīng)兩個(gè)窗格,但是手機(jī)屏幕卻只能分別顯示。所以,如果你想實(shí)現(xiàn)這些布局,你就需要以下文件:

res/layout/main.xml.單個(gè)窗格(默認(rèn))布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>

res/layout-large/main.xml,兩個(gè)窗格布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="400dp"
              android:layout_marginRight="10dp"/>
    <fragment android:id="@+id/article"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.ArticleFragment"
              android:layout_width="fill_parent" />
</LinearLayout>

注意第二個(gè)布局文件的目錄名字“l(fā)arge qualifier”,在大尺寸的設(shè)備屏幕時(shí)(比如7寸平板或者其他大屏幕的設(shè)備)就會(huì)選擇該布局文件,而其他比較小的設(shè)備則會(huì)選擇沒有限定詞的另一個(gè)布局(也就是第一個(gè)布局文件)。

使用最小寬度限定詞

在Android 3.2之前,開發(fā)者還有一個(gè)困難,那就是Android設(shè)備的“l(fā)arge”屏幕尺寸,其中包括Dell Streak(設(shè)備名稱),老版Galaxy Tab和一般的7寸平板,有很多的應(yīng)用都想針對(duì)這些不同的設(shè)備(比如5和7寸的設(shè)備)定義不同的布局,但是這些設(shè)備都被定義為了large尺寸屏幕。也是因?yàn)檫@個(gè),所以Android在3.2的時(shí)候開始使用最小寬度限定詞。

最小寬度限定詞允許你根據(jù)設(shè)備的最小寬度(dp單位)來指定不同布局。比如,傳統(tǒng)的7寸平板最小寬度為600dp,如果你希望你的UI能夠在這樣的屏幕上顯示兩個(gè)窗格(不是一個(gè)窗格顯示在小屏幕上),你可以使用上節(jié)中提到的使用同樣的兩個(gè)布局文件。不同的是,使用sw600來指定兩個(gè)方框的布局使用在最小寬度為600dp的設(shè)備上。

res/layout/main.xml,單個(gè)窗格(默認(rèn))布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>

res/layout-sw600dp/main.xml,兩個(gè)方框布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="400dp"
              android:layout_marginRight="10dp"/>
    <fragment android:id="@+id/article"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.ArticleFragment"
              android:layout_width="fill_parent" />
</LinearLayout>

這樣意味著當(dāng)你的設(shè)備的最小寬度等于600dp或者更大時(shí),系統(tǒng)選擇layout-sw600dp/main.xml(兩個(gè)窗格)的布局,而小一點(diǎn)的屏幕則會(huì)選擇layout/main.xml(單個(gè)窗格)的布局。 然而,在3.2之前的設(shè)備上,這樣做并不是很好的選擇。因?yàn)?.2之前還沒有將sw600dp作為一個(gè)限定詞出現(xiàn),所以,你還是需要使用large限定詞來做。因此,你還是應(yīng)該要有一個(gè)布局文件名為res/layout-large/main.xml,和res/layout-sw600dp/main.xml一樣。在下一節(jié)中,你將學(xué)到如何避免像這樣出現(xiàn)重復(fù)的布局文件。

使用布局別名

最小寬度限定詞只能在android3.2或者更高的版本上使用。因此,你還是需要使用抽象尺寸(small,normal,large,xlarge)來兼容以前的版本。比如,你想要將你的UI設(shè)計(jì)為在手機(jī)上只顯示一個(gè)方框的布局,而在7寸平板或電視,或者其他大屏幕設(shè)備上顯示多個(gè)方框的布局,你可能得提供這些文件:

  • res/layout/main.xml:?jiǎn)蝹€(gè)窗格布局

  • res/layout-large:多個(gè)窗格布局

  • res/layout-sw600dp:多個(gè)窗格布局

最后兩個(gè)文件都是一樣的,因?yàn)槠渲幸粋€(gè)將會(huì)適配Android3.2的設(shè)備,而另外一個(gè)則會(huì)適配其他Android低版本的平板或者電視。 為了避免這些重復(fù)的文件(維護(hù)讓人感覺頭痛就是因?yàn)檫@個(gè)),你可以使用別名文件。比如,你可以定義如下布局:

  • res/layout/main.xml,單個(gè)方框布局
  • res/layout/main_twopans.xml,兩個(gè)方框布局

然后添加這兩個(gè)文件:

  • res/values-large/layout.xml:
<resources>
    <item name="main" type="layout">@layout/main_twopanes</item>
</resources>
  • res/values-sw600dp/layout.xml:
    <resources>
      <item name="main" type="layout">@layout/main_twopanes</item>
    </resources>

    最后兩個(gè)文件擁有相同的內(nèi)容,但它們并沒有真正意義上的定義布局。它們只是將main_twopanes設(shè)置成為了別名main,它們分別處在large和sw600dp選擇器中,所以它們能適配Android任何版本的平板和電視(在3.2之前平板和電視可以直接匹配large,而3.2或者以上的則匹配sw600dp)。

使用方向限定詞

有一些布局不管是在橫向還是縱向的屏幕配置中都能顯示的非常好,但是更多的時(shí)候,適當(dāng)?shù)恼{(diào)整一下會(huì)更好。在News Reader應(yīng)用例子中,以下是布局在不同屏幕尺寸和方向的行為:

  • 小屏幕,縱向:一個(gè)窗格加logo
  • 小屏幕,橫向:一個(gè)窗格加logo
  • 7寸平板,縱向:一個(gè)窗格加action bar
  • 7寸平板,橫向:兩個(gè)寬窗格加action bar
  • 10寸平板,縱向:兩個(gè)窄窗格加action bar
  • 10寸平板,橫向:兩個(gè)寬窗格加action bar
  • 電視,橫向:兩個(gè)寬窗格加action bar

這些每個(gè)布局都會(huì)在res/layout目錄下定義一個(gè)xml文件,如此,應(yīng)用就能根據(jù)屏幕配置的變化根據(jù)別名匹配到對(duì)應(yīng)的布局來適應(yīng)屏幕。

res/layout/onepane.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>

res/layout/onepane_with_bar.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout android:layout_width="match_parent"
                  android:id="@+id/linearLayout1"
                  android:gravity="center"
                  android:layout_height="50dp">
        <ImageView android:id="@+id/imageView1"
                   android:layout_height="wrap_content"
                   android:layout_width="wrap_content"
                   android:src="@drawable/logo"
                   android:paddingRight="30dp"
                   android:layout_gravity="left"
                   android:layout_weight="0" />
        <View android:layout_height="wrap_content"
              android:id="@+id/view1"
              android:layout_width="wrap_content"
              android:layout_weight="1" />
        <Button android:id="@+id/categorybutton"
                android:background="@drawable/button_bg"
                android:layout_height="match_parent"
                android:layout_weight="0"
                android:layout_width="120dp"
                style="@style/CategoryButtonStyle"/>
    </LinearLayout>
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>

res/layout/twopanes.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="400dp"
              android:layout_marginRight="10dp"/>
    <fragment android:id="@+id/article"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.ArticleFragment"
              android:layout_width="fill_parent" />
</LinearLayout>

res/layout/twopanes_narrow.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="200dp"
              android:layout_marginRight="10dp"/>
    <fragment android:id="@+id/article"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.ArticleFragment"
              android:layout_width="fill_parent" />
</LinearLayout>

現(xiàn)在所有可能的布局我們都已經(jīng)定義了,唯一剩下的問題是使用方向限定詞來匹配對(duì)應(yīng)的布局給屏幕。這時(shí)候,你就可以使用布局別名的功能了:

res/values/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/onepane_with_bar</item>
    <bool name="has_two_panes">false</bool>
</resources>

res/values-sw600dp-land/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/twopanes</item>
    <bool name="has_two_panes">true</bool>
</resources>

res/values-sw600dp-port/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/onepane</item>
    <bool name="has_two_panes">false</bool>
</resources>

res/values-large-land/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/twopanes</item>
    <bool name="has_two_panes">true</bool>
</resources>

res/values-large-port/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/twopanes_narrow</item>
    <bool name="has_two_panes">true</bool>
</resources>

使用.9.png圖片

支持不同的屏幕尺寸同時(shí)也意味著你的圖片資源也必須能兼容不同的屏幕尺寸。比如,一個(gè)button的背景圖片就必須要適應(yīng)該button的各種形狀。

如果你在使用組件時(shí)可以改變圖片的大小,你很快就會(huì)發(fā)現(xiàn)這是一個(gè)不明確的選擇。因?yàn)檫\(yùn)行的時(shí)候,圖片會(huì)被拉伸或者壓縮(這樣容易造成圖片失真)。避免這種情況的解決方案就是使用點(diǎn)9圖片,這是一種能夠指定哪些區(qū)域能夠或者不能夠拉伸的特殊png文件。

因此,在設(shè)計(jì)的圖片需要與組件一起變大變小時(shí),一定要使用點(diǎn)9.若要將位圖轉(zhuǎn)換為點(diǎn)9,你可以用一個(gè)普通的圖片開始(下圖,是在4倍變焦情況下的圖片顯示)。 http://wiki.jikexueyuan.com/project/android-training-geek/images/button.png" alt="" />

你可以通過sdk中的draw9patch程序(位于tools/directory目錄下)來畫點(diǎn)9圖片。通過沿左側(cè)和頂部邊框繪制像素來標(biāo)記應(yīng)該被拉伸的區(qū)域。也可以通過沿右側(cè)和底部邊界繪制像素來標(biāo)記。就像下圖所示一樣:

http://wiki.jikexueyuan.com/project/android-training-geek/images/button_with_marks.png" alt="" />

請(qǐng)注意,上圖沿邊界的黑色像素。在頂部邊框和左邊框的那些表明圖像的可拉伸區(qū)域,右邊和底部邊框則表示內(nèi)容應(yīng)該放置的地方。

此外,注意.9.png這個(gè)格式,你也必須用這個(gè)格式,因?yàn)橄到y(tǒng)會(huì)檢測(cè)這是一個(gè)點(diǎn)9圖片而不是一個(gè)普通PNG圖片。

當(dāng)你將這個(gè)應(yīng)用到組件的背景的時(shí)候(通過設(shè)置android:background="@drawable/button"),android框架會(huì)自動(dòng)正確的拉伸圖像以適應(yīng)按鈕的大小,下圖就是各種尺寸中的顯示效果:

http://wiki.jikexueyuan.com/project/android-training-geek/images/buttons_stretched.png" alt="" />