Android文本时钟 — Part2
本文由 ImportNew - 余炬鹏 翻译自 stylingandroid。如需转载本文,请先参见文章末尾处的转载要求。
ImportNew注:此系列教程译者正在招募中,如果你也对此感兴趣,欢迎加入我们的 Android开发 小组。联系方式请查看小组简介。
在上一篇文章中,我们建立了一个Text Clock应用程序,并且把编写了一些业务逻辑代码。在这篇文章里,我们将开始创建一个能够添加到手机home页的小控件。
我们需要做的第一件事是创建一个小应用程序,同时实例化一个 AppWidgetProvider 对象。下面是一个简单示例:
public class TextClockAppWidget extends AppWidgetProvider {
private Context context = null;
@Override
public void onUpdate(Context context,
AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
this.context = context;
}
}
操作系统通过调用以上代码进行应用程序管理。这时,我们仅仅保存了一个以后将会用到的 Context 引用(上下文引用)。AppWidgetProvider 继承自 BroadcastReceiver,因此我们需要在
Manifest 中声明它。然而,因为 AppWidgetProvider 是一种特殊的 BroadcastReceiver,所以还需要为 AppWidgetProvider 在XML文件中额外添加一些元数据。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.stylingandroid.textclock">
<uses-sdk
android:minSdkVersion="3"
android:targetSdkVersion="17"/>
<application
android:icon="@drawable/icon"
android:label="@string/app_name">
<receiver android:name=".TextClockAppWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info"/>
</receiver>
</application>
</manifest>
appwidget_info 文件的内容如下:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="110dp"
android:minHeight="40dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/appwidget"
android:previewImage="@drawable/widget"
android:resizeMode="none">
</appwidget-provider>;
这个文件在程序运行时会转解析为 AppWidgetProviderInfo 实例,让我们一起来看看它包含的属性:
-
minWidth和maxWidth:用来设置界面的大小,并且都默认值。在这个应用中,我们将创建一个大小为2×1(格子)的小控件(widget)。关于这些参数的详细解释请参见这里。 -
updatePeriodMillis:系统调用AppWidgetProvider更新应用的频率,参数设置的值取决于应用的实际需要。然而,这种机制支持的最大更新速率为30分钟/次,但一个时钟30分钟更新一次显然是不现实的。因此我们需要选择其它的更新机制,这里就先使用默认值。 -
initialLayout:小控件的默认布局属性,在添加到用户home页时会自动显示。我们将在下文中简要地讨论该布局。 -
previewImage:在使用API 11(Honeycomb 3.0)的设备及更新版本中,可以在选择器中添加预览图片。我们会添加截屏功能,但是此功能不支持API 12之前版本的设备。 -
resizeMode:从API 12(Honeycomb 3.1)开始就支持重置小控件的大小。这里我们使用的是固定大小。再一次说明,API 12之前的设备不支持该属性。
我们或许能猜到 initialLayout 属性需要创建一个布局文件 res/layout/appwidget.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="@dimen/widget_margin">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/widget_background"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:paddingLeft="12dp"
android:paddingRight="0dp">
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
style="@style/hoursTextWidget"
android:gravity="bottom"
android:id="@+id/hours"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/minutesTextWidget"
android:layout_marginTop="-8dp"
android:layout_marginBottom="-8dp"
android:id="@+id/tens"/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
style="@style/minutesTextWidget"
android:id="@+id/minutes"/>
</LinearLayout>
</FrameLayout>
这里,我们采用线性布局 LinearLayout,设置了背景,并且包含三个用来显示文本 TextView。同时我们为这些控件都设置了自己的样式风格,我们会在后面做简要介绍。或许你还存在一点疑问:为什么把所有布局的相关内容都放进一个FrameLayout里面——这样把 LinearLayout 放在 FrameLayout 中效率会不会变低?这样做的原因是:在API 14(Ice Cream Sandwich)中,应用小控件的边框行为被改变了,系统会自动为应用加上边框。为了维持旧版和新版的统一,我们需要为API 14前的设备补上一个边框值。为了实现这个目标,我们增加了一个文件 res/values/dimens.xml,在这个文件中定义了 @dimen/widget_margin:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="widget_margin">8dp</dimen>
<dimen name="widget_text_height">22dp</dimen>
</resources>
对于版本较老的设备,手动添加边框没有问题。但在API 14及以后的设备上系统会自动设置边框,因此我们有必要自己重新进行设。我们可以创建 res/values-v14/dimens.xml,在系统设置边框的时会在这个文件中寻找设置的值:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="widget_margin">0dp</dimen>
</resources>
LinearLayout 的背景在文件 res/drawable/widget_background.xml 中定义:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp"/>
<solid android:color="#AA000000"/>
<stroke
android:color="@color/holo_blue_light"
android:width="1dp"/>
</shape>
上面的文件中定义了一个圆角、半透明的矩形,并且带有浅蓝色、holo风格的轮廓。
然后,在文件 res/values/styles.xml 中定义了文本的样式:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="hoursTextWidget">
<item name="android:textSize">@dimen/widget_text_height</item>
<item name="android:textColor">@color/holo_blue_bright</item>
<item name="android:textStyle">bold</item>
</style>
<style name="minutesTextWidget" parent="hoursTextWidget">
<item name="android:textColor">@color/holo_blue_light</item>
<item name="android:textStyle">normal</item>
</style>
</resources>
最后,需要定义我们使用的颜色。这些颜色必须能在支持holo的系统上使用。为了做到向后兼容,我们将他们包含在 res/values/colors.xml 中:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="holo_blue_bright">#ff00ddff</color>
<color name="holo_blue_light">#ff33b5e5</color>
</resources>
在这里我们讲的内容有点多了,但多数都是对之前讲过的进行深化,所以快速浏览下即可。
要了解项目现在进展如何,如果安装这个程序,就能在设备上的小控件选择页上看见自己的应用并且还带有预览:

如果把这个小控件拖到home页,上面所设置的样式和背景则会全部显示出来。但是,因为现在没有给 TextView 控件添加文字,所以不会显示任何内容。

在下一篇文章,我们会在 TextView 中显示当前的时间。
本文的源代码可以在这里找到,
同时你也可以在Google Play上找到此应用。
原文链接: stylingandroid 翻译: ImportNew.com - 余炬鹏
译文链接: http://www.importnew.com/8941.html
[ 转载请保留原文出处、译者和译文链接。]
相关文章
- Android文本时钟 — Part1
- 有效处理Java异常三原则
- Android一周开发要闻 – 第一期字幕
- 深入理解JDBC的超时设置
- 用Android应用开发Android应用
- Scala教程:简单构建工具SBT
- 如何为Eclipse JFace UI运行单元测试
- SPRING SECURITY JAVA配置:Web Security
- JVM并发机制的探讨——内存模型、内存可见性和指令重排序
- HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap