Android 官方 Training 文檔學習總結系列
官方 Training 總結系列第二篇:支持不同的設備。
支持不同的語言
在任何情況下,從應用代碼中提取 UI 字符串并將其存放在外部文件中都是個好辦法。Android 可以通過工程中的資源目錄輕松實現這一功能。
創建語言區域目錄和字符串文件
如需添加對更多語言的支持,在res/中創建一個額外的values目錄,并以連字符和ISO國家代碼結尾命名。例如,values-es/ 目錄包含的簡單資源用于語言代碼為“es”的語言區域。Android 根據運行時設備的語言區域設置加載相應的資源。
一旦確定了為哪些語言提供支持,便可創建資源子目錄和字符串資源文件。例如:
MyProject/
?? res/
????values/
??????strings.xml
????values-es/
??????strings.xml
????values-fr/
??????strings.xml
將各個語言區域的字符串值添加到相應文件中。
在運行時,Android 系統會根據當前為用戶設備設置的語言區域使用相應的字符串資源集。
例如:英文,/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">My Application</string>
<string name="hello_world">Hello World!</string>
</resources>
西班牙文,/values-es/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">Mi Aplicación</string>
<string name="hello_world">Hola Mundo!</string>
</resources>
注:可以在任何資源類型上使用語言區域限定符(或任何配置限定符),例如,可以提供本地化版本的可繪制位圖。
使用字符串資源
可以在源代碼和其他 XML 文件中通過 < string >元素的 name 屬性來引用自己的字符串資源。
在源代碼中,可以使用語法 R.string.< string_name > 引用字符串資源。有許多方法都接受以這種方式引用的字符串資源。
例如:
// Get a string resource from your app's Resources
String hello = getResources().getString(R.string.hello_world);
// Or supply a string resource to a method that requires a string
TextView textView = new TextView(this);
textView.setText(R.string.hello_world);
在其他 XML 文件中,只要 XML 屬性接受字符串值,可以使用語法 @string/<string_name> 引用字符串資源。
例如:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
適配不同的屏幕
Android 使用兩種常規屬性對不同的設備屏幕進行分類:尺寸和密度。我們應該在 APP 中包含一些替代資源,來適應不同的屏幕尺寸和密度,以優化 APP 的外觀。
- 4 種普遍尺寸:小(small),普通(normal),大(large),超大(xlarge)
- 4 種普遍密度:低精度(ldpi), 中精度(mdpi), 高精度(hdpi), 超高精度(xhdpi)
要為不同的屏幕聲明不同的 layout 和 bitmap,必須將這些替代資源放在不同的目錄中,類似于對不同語言字符串的做法
另請注意,屏幕方向(橫向或縱向)被認為是屏幕尺寸的變化,因此許多應用程序應修改 layout,以優化每個方向的用戶體驗。
創建不同的 layout
要在不同的屏幕尺寸上優化用戶體驗,應該為要支持的每個屏幕尺寸創建一個唯一的布局 XML 文件。每個 layout 都應該保存到相應的資源目錄中,并以 -< screen_size > 為后綴命名。例如,大尺寸屏幕(large screens)的唯一的 layout 文件應該保存在 res/layout-large/ 中。
注意: 為了匹配合適的屏幕尺寸Android會自動地測量我們的layout文件。所以不需要因不同的屏幕尺寸去擔心UI元素的大小,而應該專注于layout結構對用戶體驗的影響。(比如關鍵視圖相對于同級視圖的尺寸或位置)
例如,此項目包括默認 layout 和大尺寸屏幕的替代布局:
MyProject/
?? res/
????layout/
??????main.xml
????layout-large/
??????main.xml
layout 文件的名字必須完全一樣,為了對相應的屏幕尺寸提供最優的 UI,文件的內容不同。
如平常一樣在 app 中簡單引用:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
系統會根據 app 所運行的設備屏幕尺寸,在與之對應的 layout 目錄中加載 layout。
注意:Android 3.2及以上版本支持定義屏幕尺寸的高級方法,它允許我們根據屏幕最小長度和寬度,為各種屏幕尺寸指定與密度無關的layout資源。
創建不同的位圖
應該為 4 種普遍密度(分辨率):低,中,高,超高精度,都提供相適配的 bitmap 資源。這能使 app 在所有屏幕分辨率中都能有良好的畫質和效果。
要生成這些圖像,應該從原始的矢量圖像資源著手,然后根據下列尺寸比例,生成各種密度下的圖像。
- xhdpi: 2.0
- hdpi: 1.5
- mdpi: 1.0 (基準)
- ldpi: 0.75
這意味著,如果針對 xhdpi 的設備生成了一張 200x200 的圖像,那么應該為 hdpi 生成 150x150,為 mdpi 生成 100x100, 和為 ldpi 生成 75x75 的圖片資源。
然后,將文件放在相應的 drawable 資源目錄中:
MyProject/
?? res/
???? drawable-xhdpi/
??????awesomeimage.png
????drawable-hdpi/
??????awesomeimage.png
????drawable-mdpi/
??????awesomeimage.png
????drawable-ldpi/
??????awesomeimage.png
任何時候引用@ drawable / awesomeimage,系統都會根據屏幕的密度選擇適當的 bitmap。
注意:低密度(ldpi)資源是非必要的,當提供了hdpi的圖像,系統會把hdpi的圖像按比例縮小一半,去適配ldpi的屏幕。
支持不同的平臺版本
一般情況下,在更新 app 至最新 Android 版本時,最好先保證新版的 app 可以支持 90% 的設備使用。
注:為了能在幾個 Android 版本中都能提供最好的特性和功能,應該在我們的 app 中使用 Android Support Library,它能使我們的app能在舊平臺上使用最近的幾個平臺的APIs。
指定最小和目標API級別
AndroidManifest.xml 文件中描述了 app 的細節及 app 支持哪些 Android 版本。具體來說,< uses-sdk > 元素中的 minSdkVersion 和 targetSdkVersion 屬性,標明在設計和測試 app 時,最低兼容 API 的級別和最高適用的 API 級別(這個最高的級別是需要通過測試的)。例如:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ... >
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15" />
...
</manifest>
隨著新版本 Android 的發布,一些風格和行為可能會改變,為了能使app能利用這些變化,而且能適配不同風格的用戶的設備,應該將 targetSdkVersion 的值盡量的設置與最新可用的 Android 版本匹配。
運行時檢查系統版本
Android 在 Build 常量類中提供了對每一個版本的唯一代號,在 app 中使用這些代號可以建立條件,保證依賴于高級別的 API 的代碼,只會在這些 API 在當前系統中可用時,才會執行。
private void setUpActionBar() {
// Make sure we're running on Honeycomb or higher to use ActionBar APIs
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
注意:當解析 XML 資源時,Android 會忽略當前設備不支持的 XML 屬性。所以可以安全地使用較新版本的 XML 屬性,而不需要擔心舊版本 Android 遇到這些代碼時會崩潰。例如如果設置 targetSdkVersion="11",app 會在 Android 3.0 或更高時默認包含 ActionBar。然后添加 menu items到 action bar 時,需要在自己的 menu XML 資源中設置 android:showAsAction="ifRoom"。在跨版本的 XML 文件中這么做是安全的,因為舊版本的 Android 會簡單地忽略 showAsAction 屬性(就是這樣,你并不需要用到 res/menu-v11/ 中單獨版本的文件)。
使用平臺樣式和主題
Android 提供了用戶體驗主題,為 app 提供基礎操作系統的外觀和體驗。這些主題可以在 manifest 文件中被應用于 app 中。通過使用內置的風格和主題,app 自然地隨著 Android 新版本的發布,自動適配最新的外觀和體驗。
使 activity 看起來像對話框:
<activity android:theme="@android:style/Theme.Dialog">
使 activity 有一個透明背景:
<activity android:theme="@android:style/Theme.Translucent">
應用在 /res/values/styles.xml 中定義的自定義主題:
<activity android:theme="@style/CustomTheme">
使整個app應用一個主題(全部 activities )在元素中添加 android:theme 屬性:
<application android:theme="@style/CustomTheme">
ikook
2017.03.21