Upload
eosin-chen
View
45.154
Download
9
Embed Size (px)
Citation preview
Section 1:
發生了什麼事?解析度與元件的關係。
Section 2:
實機上的畫面,不是都用模擬器設計好了嗎?
Section 3:
憤怒鳥的背景,圖片大小與解析度的對應。
Section 4:
翻來翻去,直立橫放都要處理。
Section 5:
Layout 的意義與應用
學生實作 發現問題 討論與研究 解法與意義
問題的起源,就發生在這些手機上..
除了品牌不同,這些都是 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 Android 2.1 1024MB WQVGA400
AVD_21_WVGA800 Android 2.1 1024MB WVGA800
新增完畢後,啟動這四個 AVD,並於啟動時,記錄其螢幕解析度 (如 QVGA = 240 x 320) 與 Density(如 QVGA=120(Low))
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 執行
1. 打開 Test1 專案的 res\layout\main.xml
2. 切換到 main.xml 頁(非圖形化介面)
3. 加入以下的按鈕
<Button
android:id="@+id/btnTest1"
android:text="測試"
android:layout_width="fill_parent"
android:layout_height="300px" />
4. 於不同的 AVD 執行看看
同一個程式,在不同的 AVD 上執行,有何差異?
此差異的原因?
此差異會造成怎樣的困擾?
避免差異的方向?
元件的 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
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
討論:為何 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
注意比例關係
手機真實尺寸
與執行結果
機型 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
由於各廠商並未提供螢幕真實尺寸,故以上數據皆由網站而來, 與真實情況可能稍有誤差
資料來源: http://developer.android.com/guide/practices/screens_support.html http://developer.android.com/resources/dashboard/screens.html
Actual size 定義實機面板大小的等級類別 Actual density 為密度與名稱上的定義
觀察 “300dp轉換後的尺寸”,得到怎樣的結論?
試分析為何 Android 推薦這樣的轉換?
轉換後,對使用者的影響為何?是好還是壞?
觀念挑戰:若要設計一個”手機皮尺”程式,即利用
手機來量真正物體的長度,會遇到怎樣的問題?
圖片的大小與解析度
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"
/>
圖片來源:http://developer.android.com/guide/practices/screens_support.html
同一張圖片,在不同的解析度下的情況
依照不同的解析度,製作不同的圖片(三張),顯示的結果
發生了什麼現象?
對使用者友善的解決方式為何?
需要在不同的 dpi 手機上,顯示相同大小的圖片時,有兩種方式: ◦ 寫程式碼,動態針對不同的螢幕解析度,進行縮放
=> 效果不好,且會拖慢執行速度
◦ 製作不同尺寸的圖片,同檔名,放到三個資料夾中 => 效果好,但若圖片太多,到時 apk 會變得比較大
當程式執行時,會根據目前螢幕的dpi,自動到drawable-hdpi、drawable-mdpi、 drawable-ldpi中,找相對應的圖形檔。
圖片設計的流程:先設計出 mdpi 的圖形,放大 150%成為 hdpi,縮小 75% 成為 ldpi 的圖。
如何設計出如 Angry Bird 般
可以動態縮放的遊戲圖片背景?
當螢幕翻轉時
將會結束目前的 Activity, 並重新 Create 一個新的。
所以: 1. 程式中要在適當(OnPause)的時
候,儲存相關資訊,如使用者於 EditText 中輸入的文字
2. 設計直立(LANDSCAPE)與橫向(PORTRAIT),不同的畫面
3. 於 OnCreate 或 OnResume中,
取回儲存的資料,放到程式的資料結構與畫面中
討論: 1. 資料要存去哪兒?
2. 怎麼設計不同的畫面?
1. 在 Eclipse 的專案目錄下,/res 之下,建立 layout-land 與 layout-port 兩個目錄。
2. layout-land 代表直式的畫面,layout-port 代表橫式的畫面。
3. 依照直與橫的螢幕特性,建立不同的畫面檔
4. 此畫面檔(xml),會在 Activity 的 OnCreate 中,被讀出與建立 setContentView(R.layout.main);
在兩個畫面中,加入不同的 TextView 來顯示在不同的方向中 <TextView android:layout_width="fill_parent“ android:layout_height="wrap_content“ android:text="It's LAND/PORT layout“ />
在模擬器中,利用 Ctrl+F11 來翻轉螢幕。
方法如下: 在 AndroidManifest.xml 中,每個 Activity 加入如下的設定: <activity android:name=".SubscribeBusStop“ android:configChanges="orientation"> </activity>
這樣,就不會重新產生 Activity
若有 layout-land 與 layout-port 時,原來的
layout 是否有作用?
如何強制設定,此 Activity 的限制方向?
如何取得目前螢幕的方向?
如何動態設定 Activity 的方向?
Layout與畫面布局
畫面上只有單一 Button元件,
layout_width=300dp,layout_height=200dp,
此 Button 不管在何種螢幕尺寸/方向下,
皆保持在螢幕正中央。
Layout 為預先設定好的元件排列方式。
利用 Layout,可以快速、有結構的安排畫面元件,依照預定的方式呈現。
Layout中,除了放置元件之外,還可放入另一個Layout,形成巢狀結構。
Android 中的 Layout 有以下五種 LinearLayout FrameLayout RelativeLayout TableLayout AbsoluteLayout(已不再使用)
線性佈局就是將在< LinearLayout >內的元件以線性的方式來呈現
<?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):
線性佈局共有兩個方向: ◦ 垂直(vertical)
◦ 水平(horizontal)
◦ 決定垂直或是水平的屬性為Orientation
android:orientation ◦ 在<LinearLayout>中,此屬性代表元件的排列是垂直或水平佈局
android:layout_width ◦ 代表此元件佈局的寬度,若值為fill_parent則會填滿
parent的寬度;若值為wrap_content則元件寬度會依照內容大小而調整
android:layout_height ◦ 代表此元件佈局的高度,若值為fill_parent則會填滿
parent的高度;若值為wrap_content則元件高度會依照內容大小而調整
android:layout_margin ◦ 指定這個view距離上下左右的額外距離
android: layout_marginBottom ◦ 指定這個view距離下方的額外距離
android: layout_marginLeft ◦ 指定這個view距離左方的額外距離
android: layout_marginRight ◦ 指定這個view距離右方的額外距離
android: layout_marginTop ◦ 指定這個view距離上方的額外距離
FrameLayout是所有佈局中最單純的
若同個FrameLayout中若有數個元件
◦ 以最上層的元件為主
若同個FrameLayout中有同大小的元件
◦ 只會看到最上層的元件
若同個FrameLayout中有不同大小的元件
◦ 會看到由下至上的元件
<?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) :
<!-- 最上層的元件 -->
<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):
<!-- 顯示第一行的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):
<?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
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的左邊界同位置
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元件的下方
android:layout_centerHorizontal ◦ 若為true,置於Parent水平位置的中心
android:layout_centerInParent ◦ 若為true,置於Parent水平以及垂直位置的中心
android:layout_centerVertical ◦ 若為true,置於Parent垂直位置的中心
android:layout_toLeftOf/toRightOf ◦ 置於目標id元件的左方/右方
<?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):
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>
</TableLayout>
布局文件-2(res/layout/main.xml):
相關的屬性,和 TableRow 的架構與組成,很多..
所以,TableLayout 的完全設計..
這是,另外一個故事了..
會選擇用哪個 Layout 來完成
”按鈕皆保持在螢幕正中央”
呢?
在不同的 Layout 中,或是在巢狀的 Layout 內,
Parent 是誰?
fill_parent 會有何結果?是否為最佳的設計方式?
利用程式碼來取得 parent 的 parent,並用來做為
元件的大小標準,是否可行?有何意義?
所有元件,最根的parent是誰?
Q & A 請不要鞭得太用力 :-)