*以下內(nèi)容翻譯自android wear的官方教程,本人水平有限,如有錯誤歡迎指出
home
以下正文
手表使用了與手機相同的布局技術(shù),但有一些需要考慮的約束。在手機上設(shè)計UI和功能的經(jīng)驗在手表上并不會都取得成功。如果你想知道怎么設(shè)計優(yōu)秀的手表應用,你可以閱讀android 手表設(shè)計參考.
當你在創(chuàng)建一個android wear應用的時候,你必須考慮手表的形狀。比如方形手表上設(shè)計的app在圓形手表上四角的內(nèi)容都會被剪切。 一個在油管上的示范。
以下是一個悲慘案例:

<LinearLayout mlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_square" />
</LinearLayout>
這個文本被悲劇的閹割了。
Wearable UI Library提供了兩個方法來解決這個問題:
- 定義兩個不同的layout來分別定義圓形和方形的界面,你的app會在運行的時候自動檢測設(shè)備的形狀并選擇合適的layout來顯示信息
- 使用一個特殊的layout,這個layout會根據(jù)設(shè)備的形狀產(chǎn)生不同的顯示效果
如果你想你的app在不同形狀的設(shè)備上顯示不一樣的效果,你可以選擇方法1。如果你用第二種方法,你將會在兩個設(shè)備上得到一個相似的界面。
添加Wearable UI Library
Android Studio 默認在你的wear module當中包含了Wearable UI Library 。為了在你的project當中包含這個library,請確保 Extras > Google Repository 這個包已經(jīng)安裝到了你的android SDK當中,同時要保證你的wear module的build.gradle包含了以下依賴(dependency)
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.support:wearable:+'
compile 'com.google.android.gms:play-services-wearable:+'
}```
在接下的layout技術(shù)實現(xiàn)中,’com.google.android.support:wearable‘這個玩意是必要的。
如果你想更了解她,這里有她的[API文檔](http://developer.android.youdaxue.com/reference/android/support/wearable/view/package-summary.html)
#為不同的形狀指定不同的layout
在Wearable UI Library中的[WatchViewStub](http://developer.android.youdaxue.com/reference/android/support/wearable/view/WatchViewStub.html)這個類可以幫你不同形狀設(shè)備上指定不同的layout在。這個類會在運行時檢測設(shè)備的形狀然后加載(inflates)正確的layout。
使用方法:
1. 你的activity的layout用WatchViewStub作為根節(jié)點
2. 定義一個方形的layout,然后在rectLayout屬性上指定它
3. 定義一個圓形的layout,然后在roundLayout屬性上指定它
*示例*
```xml
<android.support.wearable.view.WatchViewStub
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rectLayout="@layout/rect_activity_wear"
app:roundLayout="@layout/round_activity_wear">
</android.support.wearable.view.WatchViewStub>
在你的activity當中加載(inflate)這個layout
@Overrideprotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wear);
}
當然,除了上述步驟之外,你還必須創(chuàng)建res/layout/rect_activity_wear.xml
和 res/layout/round_activity_wear.xml 兩個layout。創(chuàng)建這兩個layout所使用的語法和技術(shù)與在android 手機上開發(fā)是完全一樣的,但是你必須考錄手表的屏幕的大小和形狀。如果你完成了上述的步驟,那么系統(tǒng)就會自動的在正確的設(shè)備上加載正確的layout.
訪問layout上的控件(views)
在WatchViewStub檢測設(shè)備的形狀之前,你的layout尚未被指定,所以你不能馬上訪問控件。為了訪問你的控件,你需要在你的activity當中設(shè)置一個監(jiān)聽器來監(jiān)聽WatchViewStub,這樣當WatchViewStub檢測完后,它會知會你一聲。
@Overrideprotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wear);
WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override public void onLayoutInflated(WatchViewStub stub) {
// Now you can access your views
TextView tv = (TextView) stub.findViewById(R.id.text);
...
}
});
}
使用自適應layout
在Wearable UI Library 中的BoxInsetLayout這個類可以幫助你定義同時在圓形和方形屏幕上都很贊的layout。BoxInsetLayout繼承于 FrameLayout,她可以依照不同的屏幕形狀使你的控件布局在合適的位置。
下面這張圖片中的灰色區(qū)域顯示了BoxInsetLayout會怎么自動的將你的控件布局于圓形的屏幕,控件在這個灰色區(qū)域顯示需要設(shè)置layout_box屬性。
- top,bottom,left,right四個屬性值的組合,比如"left|top"來讓控件坐落于灰色區(qū)域的左上角
- 所有的位置都是在灰色區(qū)域內(nèi)的。
在方形的屏幕上,窗口的邊框是不存在的(沒有圓形屏幕上所顯示的黑色邊角料),layout_box屬性也是被忽略的。


下面是上面布局效果的layout
<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/robot_background"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:padding="15dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
app:layout_box="all">
<TextView
android:gravity="center"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="@string/sometext"
android:textColor="@color/black" />
<ImageButton
android:background="@null"
android:layout_gravity="bottom|left"
android:layout_height="50dp"
android:layout_width="50dp"
android:src="@drawable/ok" />
<ImageButton
android:background="@null"
android:layout_gravity="bottom|right"
android:layout_height="50dp"
android:layout_width="50dp"
android:src="@drawable/cancel" />
</FrameLayout>
</android.support.wearable.view.BoxInsetLayout>
幾個注意點:
這個布局文件的根是BoxInsetLayout
BoxInsetLayout的padding="15dp" :
因為圓形屏幕的黑邊(window insets)大于15dp,所以這個屬性只對方形屏幕有效。FrameLayout的padding="5dp":
這個padding在方形和圓形的屏幕上都是有效的,所以在方形的屏幕上控件到邊緣有20dp(15+5),而在圓形屏幕上是5dp。FrameLayout的layout_box="all" :
這個屬性確保了FrameLayout本身和它的子元素都被顯示在圓形的屏幕上,對方形屏幕,這個屬性沒有用。