Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
陳信宏
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 的設計與解決方式

81,520 views

Published on

Published in: Technology

不同尺寸與解析度的螢幕下,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請不要鞭得太用力 :-)

×