*以下内容翻译自android wear的官方教程,本人水平有限,如有错误欢迎指出
home
以下正文
手表使用了与手机相同的布局技术,但有一些需要考虑的约束。在手机上设计UI和功能的经验在手表上并不会都取得成功。如果你想知道怎么设计优秀的手表应用,你可以阅读android 手表设计参考.
当你在创建一个android wear应用的时候,你必须考虑手表的形状。比如方形手表上设计的app在圆形手表上四角的内容都会被剪切。 一个在油管上的示范。
以下是一个悲惨案例:
<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会在运行的时候自动检测设备的形状并选择合适的layout来显示信息
- 使用一个特殊的layout,这个layout会根据设备的形状产生不同的显示效果
如果你想你的app在不同形状的设备上显示不一样的效果,你可以选择方法1。如果你用第二种方法,你将会在两个设备上得到一个相似的界面。
添加Wearable UI Library
Android Studio 默认在你的wear module当中包含了Wearable UI Library 。为了在你的project当中包含这个library,请确保 Extras > Google Repository 这个包已经安装到了你的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技术实现中,’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)这个类可以帮你不同形状设备上指定不同的layout在。这个类会在运行时检测设备的形状然后加载(inflates)正确的layout。
使用方法:
1. 你的activity的layout用WatchViewStub作为根节点
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);
}
当然,除了上述步骤之外,你还必须创建res/layout/rect_activity_wear.xml
和 res/layout/round_activity_wear.xml 两个layout。创建这两个layout所使用的语法和技术与在android 手机上开发是完全一样的,但是你必须考录手表的屏幕的大小和形状。如果你完成了上述的步骤,那么系统就会自动的在正确的设备上加载正确的layout.
访问layout上的控件(views)
在WatchViewStub检测设备的形状之前,你的layout尚未被指定,所以你不能马上访问控件。为了访问你的控件,你需要在你的activity当中设置一个监听器来监听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,她可以依照不同的屏幕形状使你的控件布局在合适的位置。
下面这张图片中的灰色区域显示了BoxInsetLayout会怎么自动的将你的控件布局于圆形的屏幕,控件在这个灰色区域显示需要设置layout_box属性。
- top,bottom,left,right四个属性值的组合,比如"left|top"来让控件坐落于灰色区域的左上角
- 所有的位置都是在灰色区域内的。
在方形的屏幕上,窗口的边框是不存在的(没有圆形屏幕上所显示的黑色边角料),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本身和它的子元素都被显示在圆形的屏幕上,对方形屏幕,这个属性没有用。