App Widget Design Guidelines
Standard Widget Anatomy
标准的app widget由三个组件组成:一个有界限的封装盒,一个框架和图形控制等元素。App widget可以包括一些安卓视图控件;支持文字标签,按钮和图像控制。好的设计往往在封装盒和框架之间有一些留白,框架内边界和widget控件件也有一些空白。
Note:安卓4.0之后,app widget自动在框架和封装盒之间进行了留白。
Determining a size for your widget
每一个widget必须设置minWidth和minHeight,表明它缺省状态下的最小空间。用户添加widget到主屏上,它所占用的空间比我们设置的空间要大。安卓主屏提供了网格状的空间供用户放置widget和图标。这种网格空间根据不同设备有所改变。例如,许多手持设备提供的是4x4的网格,平板电脑设备则是8x7。添加widget后,它会自动伸展占据最小数量的网格,同时也要满足minWidth和minHeight的限制。使用nine-patch背景图片和富有弹性的layout会使widget更好的匹配网格。
网格的width和height,以及自适应留白对于不同的设备会不同,可以根据下表估测所设计的widget的最小尺寸和所需的网格数量。
of Cells | AvailableSize(dp) |
1 | 40dp |
2 | 110dp |
3 | 180dp |
4 | 250dp |
... | ... |
n | 70xn-30 |
对于minWidth和minHeight的值保守赋值是个比较好的尝试,例如给一个music widget设置minWidth和minHeight时,如下:
那么minimum height应当是TextView的两倍高度外加一点文字边界。minimum width应当是TextView最小文字宽度加上Play按钮和Next按钮的最小宽度,外加一些文字边界。如下:
minWidth = 144dp + 2 x 8dp + 2 x 56dp = 272dp
minHeight = 48dp + 2 x 4dp + 56dp
Resizable widgets
从Android3.1开始,Widget可以被用户设置尺寸,这意味着minWidth和minHeight只是缺省状态下的有效数据。所以我们可以使用minResizeWidth和minResizeHeight设置最小尺寸,这是用户可以设置的最小尺寸,小于它们则不可用。
Adding margins to your app widget
向上文所描述的那样,Android4.0会自动添加标准的margin(必须设置targetSdkVersion为14或更高)。所以我们建议在app widget background形状之外不要添加额外的margins。
Designing Widget Layouts and Background Graphics
大部分widget拥有固定矩形或园角矩形的背景形状。使用nine patches定义这种形状是比较好的习惯;可以使用draw9patch工具创建Nine-patches图片。
一些widget,如使用StackView,则背景图片是透明的。那么单个选项就必须使用没有边界的nine-patch背景。
而对于widget的内容,需要使用有弹性的layout,例如RelativeLayout,LinearLayout或FrameLayout。下面是上述music widget的实例,注意到最健壮的添加margin的方式是把widget框架和内容封装到FrameLayout中
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/widget_margin">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@drawable/my_widget_background">
<TextView
android:id="@+id/song_info"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<Button
android:id="@+id/play_button"
android:layout_width="@dimen/my_button_width"
android:layout_height="match_parent" />
<Button
android:id="@+id/skip_button"
android:layout_width="@dimen/my_button_width"
android:layout_height="match_parent" />
</LinearLayout>
</FrameLayout>