陳信宏
eosinchen@gmail.com
 Section 1:
發生了什麼事?解析度與元件的關係。
 Section 2:
實機上的畫面,不是都用模擬器設計好了嗎?
 Section 3:
憤怒鳥的背景,圖片大小與解析度的對應。
 Section 4:
翻來翻去,直立橫放都要...
學生實作 發現問題 討論與研究 解法與意義
問題的起源,就發生在這些手機上..
除了品牌不同,這些都是 Android 手機..
最明顯的不同在哪兒?
解析度與元件大小
Name Target SD Card Size Skin
AVD_21_QVGA Android 2.1 1024MB QVGA
AVD_21_HVGA Android 2.1 1024MB HVGA
AVD_21_WQVGA400 Andr...
1. 於 Eclipse 中,新增一個 Android Project
2. Project Name = Test1
3. Build Target = 2.1
4. App Name = Test1
5. Package Name = nk...
1. 打開 Test1 專案的 reslayoutmain.xml
2. 切換到 main.xml 頁(非圖形化介面)
3. 加入以下的按鈕
<Button
android:id="@+id/btnTest1"
android:text="測試...
 同一個程式,在不同的 AVD 上執行,有何差異?
 此差異的原因?
 此差異會造成怎樣的困擾?
 避免差異的方向?
 元件的 weight 與 height,最好用以下的方式來定義
其大小
◦ fill_parent (填滿 parent)(伏筆:parent 是誰?)
◦ wrap_content(依照內容伸縮其大小)
◦ 使用 dp(Density-i...
 dp 的意義:
A virtual pixel unit that you should use when
defining UI layout, to express layout dimensions or
position in a ...
 討論:為何 Android 推薦用 dp 為單位?
Skin Res Density(dpi) dp px
QVGA 240 x 320 120(Low) 300dp 225px
HVGA 320 x 480 160(Medium) 300...
手機真實尺寸
與執行結果
機型 size res dpi 300dp  px px  cm
Samsung
Note
5.3 吋
800 x 1280
WXGA
大約 285 約 535 px
垂直方向約
4.77 cm
(11.42 cm)
HTC
EVO 3D
...
資料來源:
http://developer.android.com/guide/practices/screens_support.html
http://developer.android.com/resources/dashboard/s...
 觀察 “300dp轉換後的尺寸”,得到怎樣的結論?
 試分析為何 Android 推薦這樣的轉換?
 轉換後,對使用者的影響為何?是好還是壞?
 觀念挑戰:若要設計一個”手機皮尺”程式,即利用
手機來量真正物體的長度,會遇到怎樣的問題?
圖片的大小與解析度
1. 觀察 drawable-hdpi、 drawable-mdpi、
drawable-ldpi 中,icon.png 的大小。
2. 於 main.xml 中,加入下一列的元件碼。
3. 將專案執行到不同的 AVD 並察看結果。
<Imag...
圖片來源:http://developer.android.com/guide/practices/screens_support.html
同一張圖片,在不同的解析度下的情況
依照不同的解析度,製作不同的圖片(三張),顯示的結果
 發生了什麼現象?
 對使用者友善的解決方式為何?
 需要在不同的 dpi 手機上,顯示相同大小的圖片時,
有兩種方式:
◦ 寫程式碼,動態針對不同的螢幕解析度,進行縮放
=> 效果不好,且會拖慢執行速度
◦ 製作不同尺寸的圖片,同檔名,放到三個資料夾中
=> 效果好,但若圖片太多,到時 ap...
如何設計出如 Angry Bird 般
可以動態縮放的遊戲圖片背景?
當螢幕翻轉時
 將會結束目前的 Activity,
並重新 Create 一個新的。
 所以:
1. 程式中要在適當(OnPause)的時
候,儲存相關資訊,如使用者於
EditText 中輸入的文字
2. 設計直立(LANDSCAPE)與橫向
(POR...
1. 在 Eclipse 的專案目錄下,/res 之下,建立
layout-land 與 layout-port 兩個目錄。
2. layout-land 代表直式的畫面,layout-port 代
表橫式的畫面。
3. 依照直與橫的螢幕特性,...
 在兩個畫面中,加入不同的 TextView 來顯示在不
同的方向中
<TextView
android:layout_width="fill_parent“
android:layout_height="wrap_content“
andr...
 方法如下:
在 AndroidManifest.xml 中,每個 Activity 加入
如下的設定:
<activity
android:name=".SubscribeBusStop“
android:configChanges="or...
 若有 layout-land 與 layout-port 時,原來的
layout 是否有作用?
 如何強制設定,此 Activity 的限制方向?
 如何取得目前螢幕的方向?
 如何動態設定 Activity 的方向?
Layout與畫面布局
畫面上只有單一 Button元件,
layout_width=300dp,
layout_height=200dp,
此 Button 不管在何種螢幕尺寸/方向下,
皆保持在螢幕正中央。
 Layout 為預先設定好的元件排列方式。
 利用 Layout,可以快速、有結構的安排畫面元件,
依照預定的方式呈現。
 Layout中,除了放置元件之外,還可放入另一個
Layout,形成巢狀結構。
 Android 中的 Lay...
線性佈局就是將在< LinearLayout >內的元
件以線性的方式來呈現
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:or...
 線性佈局共有兩個方向:
◦ 垂直(vertical)
◦ 水平(horizontal)
◦ 決定垂直或是水平的屬性為Orientation
 android:orientation
◦ 在<LinearLayout>中,此屬性代表元件的排...
 android:layout_width
◦ 代表此元件佈局的寬度,若值為fill_parent則會填滿
parent的寬度;若值為wrap_content則元件寬度會依照
內容大小而調整
 android:layout_height
◦...
 android:layout_margin
◦ 指定這個view距離上下左右的額外距離
 android: layout_marginBottom
◦ 指定這個view距離下方的額外距離
 android: layout_marginL...
 FrameLayout是所有佈局中最單純的
 若同個FrameLayout中若有數個元件
◦ 以最上層的元件為主
 若同個FrameLayout中有同大小的元件
◦ 只會看到最上層的元件
 若同個FrameLayout中有不同大小的元...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:or...
<!-- 最上層的元件 -->
<EditText android:text="This is"
android:id="@+id/text02"
android:layout_width="wrap_content"
android:layo...
<!-- 顯示第一行的TextView -->
android:id="@+id/TextView01"
<!-- 顯示第二行的TextView -->
android:id="@+id/ TextView02"
android:layout_...
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:...
 android:layout_above
◦ 置於目標id元件的上方
 android:layout_alignBaseline
◦ 置於與目標id元件同樣的基準線上
 android:layout_alignBottom
◦ 讓自己的...
 android:layout_alignParentRight
◦ 若為true,讓自己的右邊界與Parent的右邊界同位置
 android:layout_alignParentTop
◦ 若為true,讓自己的上邊界與Parent的上...
 android:layout_centerHorizontal
◦ 若為true,置於Parent水平位置的中心
 android:layout_centerInParent
◦ 若為true,置於Parent水平以及垂直位置的中心
 ...
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:lay...
android:layout_column="0"
android:text="第二列n第一行"
android:textSize="22sp"
android:layout_marginLeft="60px"/>
<TextView
andr...
 相關的屬性,和 TableRow 的架構與組成,很多..
 所以,TableLayout 的完全設計..
 這是,另外一個故事了..
會選擇用哪個 Layout 來完成
”按鈕皆保持在螢幕正中央”
呢?
 在不同的 Layout 中,或是在巢狀的 Layout 內,
Parent 是誰?
 fill_parent 會有何結果?是否為最佳的設計方式?
 利用程式碼來取得 parent 的 parent,並用來做為
元件的大小標準,是否可行?...
Q & A請不要鞭得太用力 :-)
不同尺寸與解析度的螢幕下,Android 程式 UI 的設計與解決方式
不同尺寸與解析度的螢幕下,Android 程式 UI 的設計與解決方式
Upcoming SlideShare
Loading in …5
×

不同尺寸與解析度的螢幕下,Android 程式 UI 的設計與解決方式

67,197 views

Published on

Published in: Technology
2 Comments
95 Likes
Statistics
Notes
No Downloads
Views
Total views
67,197
On SlideShare
0
From Embeds
0
Number of Embeds
669
Actions
Shares
0
Downloads
289
Comments
2
Likes
95
Embeds 0
No embeds

No notes for slide

不同尺寸與解析度的螢幕下,Android 程式 UI 的設計與解決方式

  1. 1. 陳信宏 eosinchen@gmail.com
  2. 2.  Section 1: 發生了什麼事?解析度與元件的關係。  Section 2: 實機上的畫面,不是都用模擬器設計好了嗎?  Section 3: 憤怒鳥的背景,圖片大小與解析度的對應。  Section 4: 翻來翻去,直立橫放都要處理。  Section 5: Layout 的意義與應用
  3. 3. 學生實作 發現問題 討論與研究 解法與意義
  4. 4. 問題的起源,就發生在這些手機上.. 除了品牌不同,這些都是 Android 手機.. 最明顯的不同在哪兒?
  5. 5. 解析度與元件大小
  6. 6. Name Target SD Card Size Skin AVD_21_QVGA Android 2.1 1024MB QVGA AVD_21_HVGA Android 2.1 1024MB HVGA AVD_21_WQVGA400 Android 2.1 1024MB WQVGA400 AVD_21_WVGA800 Android 2.1 1024MB WVGA800 新增完畢後,啟動這四個 AVD,並於啟動時,記錄其螢幕解析度 (如 QVGA = 240 x 320) 與 Density(如 QVGA=120(Low))
  7. 7. 1. 於 Eclipse 中,新增一個 Android Project 2. Project Name = Test1 3. Build Target = 2.1 4. App Name = Test1 5. Package Name = nku.android 6. Create Activity = Test1Activity 7. Min SDK = 7 依照以上資料,建立專案,並於不同的 AVD 執行
  8. 8. 1. 打開 Test1 專案的 reslayoutmain.xml 2. 切換到 main.xml 頁(非圖形化介面) 3. 加入以下的按鈕 <Button android:id="@+id/btnTest1" android:text="測試" android:layout_width="fill_parent" android:layout_height="300px" /> 4. 於不同的 AVD 執行看看
  9. 9.  同一個程式,在不同的 AVD 上執行,有何差異?  此差異的原因?  此差異會造成怎樣的困擾?  避免差異的方向?
  10. 10.  元件的 weight 與 height,最好用以下的方式來定義 其大小 ◦ fill_parent (填滿 parent)(伏筆:parent 是誰?) ◦ wrap_content(依照內容伸縮其大小) ◦ 使用 dp(Density-independent pixel)為單位  改變一下 Button 的 android:layout_height,再執行 看看 資料來源: http://developer.android.com/guide/practices/screens_support.html
  11. 11.  dp 的意義: A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way.  dp 與實際像素的轉換 px = dp * (dpi / 160) 其中 dpi 為此種螢幕的 Density 資料來源: http://developer.android.com/guide/practices/screens_support.html
  12. 12.  討論:為何 Android 推薦用 dp 為單位? Skin Res Density(dpi) dp px QVGA 240 x 320 120(Low) 300dp 225px HVGA 320 x 480 160(Medium) 300dp 300px WQVGA400 240 x 400 120(Low) 300dp 225px WVGA800 480 x 800 240(High) 300dp 450px 注意比例關係
  13. 13. 手機真實尺寸 與執行結果
  14. 14. 機型 size res dpi 300dp  px px  cm Samsung Note 5.3 吋 800 x 1280 WXGA 大約 285 約 535 px 垂直方向約 4.77 cm (11.42 cm) HTC EVO 3D 4.3 吋 540 x 960 qHD 大約 256 約 480 px 垂直方向約 4.76 cm (9.52 cm) Moto Droid 3.7 吋 480 x 854 WVGA854 大約 264 約 495 px 垂直方向約 4.74 cm (8.19 cm) SE Xperia active 3.0 吋 320 x 480 HVGA 大約 160 約 300 px 垂直方向約 4.38 cm (約 7 cm) 部分數據來源網站:http://members.ping.de/~sven/dpi.html 由於各廠商並未提供螢幕真實尺寸,故以上數據皆由網站而來, 與真實情況可能稍有誤差
  15. 15. 資料來源: http://developer.android.com/guide/practices/screens_support.html http://developer.android.com/resources/dashboard/screens.html Actual size 定義實機面板大小的等級類別 Actual density 為密度與名稱上的定義
  16. 16.  觀察 “300dp轉換後的尺寸”,得到怎樣的結論?  試分析為何 Android 推薦這樣的轉換?  轉換後,對使用者的影響為何?是好還是壞?  觀念挑戰:若要設計一個”手機皮尺”程式,即利用 手機來量真正物體的長度,會遇到怎樣的問題?
  17. 17. 圖片的大小與解析度
  18. 18. 1. 觀察 drawable-hdpi、 drawable-mdpi、 drawable-ldpi 中,icon.png 的大小。 2. 於 main.xml 中,加入下一列的元件碼。 3. 將專案執行到不同的 AVD 並察看結果。 <ImageView android:id="@+id/testimg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" android:layout_x="50px" android:layout_y="50px" />
  19. 19. 圖片來源:http://developer.android.com/guide/practices/screens_support.html 同一張圖片,在不同的解析度下的情況 依照不同的解析度,製作不同的圖片(三張),顯示的結果
  20. 20.  發生了什麼現象?  對使用者友善的解決方式為何?
  21. 21.  需要在不同的 dpi 手機上,顯示相同大小的圖片時, 有兩種方式: ◦ 寫程式碼,動態針對不同的螢幕解析度,進行縮放 => 效果不好,且會拖慢執行速度 ◦ 製作不同尺寸的圖片,同檔名,放到三個資料夾中 => 效果好,但若圖片太多,到時 apk 會變得比較大  當程式執行時,會根據目前螢幕的dpi,自動到 drawable-hdpi、drawable-mdpi、 drawable- ldpi中,找相對應的圖形檔。  圖片設計的流程:先設計出 mdpi 的圖形,放大 150%成為 hdpi,縮小 75% 成為 ldpi 的圖。
  22. 22. 如何設計出如 Angry Bird 般 可以動態縮放的遊戲圖片背景?
  23. 23. 當螢幕翻轉時
  24. 24.  將會結束目前的 Activity, 並重新 Create 一個新的。  所以: 1. 程式中要在適當(OnPause)的時 候,儲存相關資訊,如使用者於 EditText 中輸入的文字 2. 設計直立(LANDSCAPE)與橫向 (PORTRAIT),不同的畫面 3. 於 OnCreate 或 OnResume中, 取回儲存的資料,放到程式的資 料結構與畫面中  討論: 1. 資料要存去哪兒? 2. 怎麼設計不同的畫面?
  25. 25. 1. 在 Eclipse 的專案目錄下,/res 之下,建立 layout-land 與 layout-port 兩個目錄。 2. layout-land 代表直式的畫面,layout-port 代 表橫式的畫面。 3. 依照直與橫的螢幕特性,建立不同的畫面檔 4. 此畫面檔(xml),會在 Activity 的 OnCreate 中, 被讀出與建立 setContentView(R.layout.main);
  26. 26.  在兩個畫面中,加入不同的 TextView 來顯示在不 同的方向中 <TextView android:layout_width="fill_parent“ android:layout_height="wrap_content“ android:text="It's LAND/PORT layout“ />  在模擬器中,利用 Ctrl+F11 來翻轉螢幕。
  27. 27.  方法如下: 在 AndroidManifest.xml 中,每個 Activity 加入 如下的設定: <activity android:name=".SubscribeBusStop“ android:configChanges="orientation"> </activity> 這樣,就不會重新產生 Activity
  28. 28.  若有 layout-land 與 layout-port 時,原來的 layout 是否有作用?  如何強制設定,此 Activity 的限制方向?  如何取得目前螢幕的方向?  如何動態設定 Activity 的方向?
  29. 29. Layout與畫面布局
  30. 30. 畫面上只有單一 Button元件, layout_width=300dp, layout_height=200dp, 此 Button 不管在何種螢幕尺寸/方向下, 皆保持在螢幕正中央。
  31. 31.  Layout 為預先設定好的元件排列方式。  利用 Layout,可以快速、有結構的安排畫面元件, 依照預定的方式呈現。  Layout中,除了放置元件之外,還可放入另一個 Layout,形成巢狀結構。  Android 中的 Layout 有以下五種 LinearLayout FrameLayout RelativeLayout TableLayout AbsoluteLayout(已不再使用)
  32. 32. 線性佈局就是將在< LinearLayout >內的元 件以線性的方式來呈現
  33. 33. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:text="這是第一列" android:textSize="22sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:text="這是第二列" android:textSize="22sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:text="這是第三列" android:textSize="22sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> 布局文件(res/layout/main.xml):
  34. 34.  線性佈局共有兩個方向: ◦ 垂直(vertical) ◦ 水平(horizontal) ◦ 決定垂直或是水平的屬性為Orientation  android:orientation ◦ 在<LinearLayout>中,此屬性代表元件的排列是垂直或 水平佈局
  35. 35.  android:layout_width ◦ 代表此元件佈局的寬度,若值為fill_parent則會填滿 parent的寬度;若值為wrap_content則元件寬度會依照 內容大小而調整  android:layout_height ◦ 代表此元件佈局的高度,若值為fill_parent則會填滿 parent的高度;若值為wrap_content則元件高度會依照 內容大小而調整
  36. 36.  android:layout_margin ◦ 指定這個view距離上下左右的額外距離  android: layout_marginBottom ◦ 指定這個view距離下方的額外距離  android: layout_marginLeft ◦ 指定這個view距離左方的額外距離  android: layout_marginRight ◦ 指定這個view距離右方的額外距離  android: layout_marginTop ◦ 指定這個view距離上方的額外距離
  37. 37.  FrameLayout是所有佈局中最單純的  若同個FrameLayout中若有數個元件 ◦ 以最上層的元件為主  若同個FrameLayout中有同大小的元件 ◦ 只會看到最上層的元件  若同個FrameLayout中有不同大小的元件 ◦ 會看到由下至上的元件
  38. 38. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <FrameLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> <!-- 最底層的元件 --> <EditText android:text="That is a framelayout example" android:id="@+id/text01" android:layout_width="wrap_content" android:layout_height="wrap_content" /> 布局文件-1 (res/layout/main.xml) :
  39. 39. <!-- 最上層的元件 --> <EditText android:text="This is" android:id="@+id/text02" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </FrameLayout> </LinearLayout> 下層元件為"That is a framelayout example" 上層元件為"Thit is" 布局文件-2(res/layout/main.xml):
  40. 40. <!-- 顯示第一行的TextView --> android:id="@+id/TextView01" <!-- 顯示第二行的TextView --> android:id="@+id/ TextView02" android:layout_below="@id/ TextView01" <!-- 顯示第三行的TextView --> android:id="@+id/ TextView03" android:layout_below="@id/ TextView02" 程式以TextView01為參考,TextView02置放在 TextView01下方,TextView03放置在TextView02下方 布局文件架構(res/layout/main.xml):
  41. 41. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:text="這是第一列" android:id="@+id/TextView01" android:textSize="30sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:text="這是第二列" android:id="@+id/TextView02" android:textSize="30sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/TextView01" /> <TextView android:text="這是第三列" android:id="@+id/TextView03" android:textSize="30sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/TextView02" /> </RelativeLayout> 布局文件架構(res/layout/main.xml): 此範例用到三個TextView,利用三個 TextView作RelativeLayout
  42. 42.  android:layout_above ◦ 置於目標id元件的上方  android:layout_alignBaseline ◦ 置於與目標id元件同樣的基準線上  android:layout_alignBottom ◦ 讓自己的下邊界與目標id元件的下邊界在同一個位置  android:layout_alignLeft ◦ 讓自己的左邊界與目標id元件的左邊界在同一位置  android:layout_alignParentBottom ◦ 若為true,讓自己的下邊界與Parent的下邊界同位置  android:layout_alignParentLeft ◦ 若為true,讓自己的左邊界與Parent的左邊界同位置
  43. 43.  android:layout_alignParentRight ◦ 若為true,讓自己的右邊界與Parent的右邊界同位置  android:layout_alignParentTop ◦ 若為true,讓自己的上邊界與Parent的上邊界同位置  android:layout_alignRight ◦ 讓自己的右邊界與目標id元件的右邊界在同一位置  android:layout_alignTop ◦ 讓自己的上邊界與目標id元件的上邊界在同一個位置  android:layout_alignWithParentIfMissing ◦ 若設為true,當參考的目標id不可用時,會以Parent為參考 目標  android:layout_below ◦ 置於目標id元件的下方
  44. 44.  android:layout_centerHorizontal ◦ 若為true,置於Parent水平位置的中心  android:layout_centerInParent ◦ 若為true,置於Parent水平以及垂直位置的中心  android:layout_centerVertical ◦ 若為true,置於Parent垂直位置的中心  android:layout_toLeftOf/toRightOf ◦ 置於目標id元件的左方/右方
  45. 45. <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TableRow android:layout_marginTop="20px"> <TextView android:layout_column="0" android:text="第一列n第一行" android:textSize="22sp" android:layout_marginLeft="60px"/> <TextView android:layout_column="1" android:text="第一列n第二行" android:textSize="22sp" android:layout_marginLeft="60px"/>/> </TableRow> <TableRow android:layout_marginTop="20px"> <TextView 布局文件-1(res/layout/main.xml):
  46. 46. android:layout_column="0" android:text="第二列n第一行" android:textSize="22sp" android:layout_marginLeft="60px"/> <TextView android:layout_column="1" android:text="第二列n第二行" android:textSize="22sp" android:layout_marginLeft="60px"/>/> </TableRow> <TableRow android:layout_marginTop="20px"> <TextView android:layout_column="0" android:text="第三列n第一行" android:textSize="22sp" android:layout_marginLeft="60px"/> <TextView android:layout_column="1" android:text="第三列n第二行" android:textSize="22sp" android:layout_marginLeft="60px"/>/> </TableRow> 布局文件-2(res/layout/main.xml):
  47. 47.  相關的屬性,和 TableRow 的架構與組成,很多..  所以,TableLayout 的完全設計..  這是,另外一個故事了..
  48. 48. 會選擇用哪個 Layout 來完成 ”按鈕皆保持在螢幕正中央” 呢?
  49. 49.  在不同的 Layout 中,或是在巢狀的 Layout 內, Parent 是誰?  fill_parent 會有何結果?是否為最佳的設計方式?  利用程式碼來取得 parent 的 parent,並用來做為 元件的大小標準,是否可行?有何意義?  所有元件,最根的parent是誰?
  50. 50. Q & A請不要鞭得太用力 :-)

×