Android文本时钟 — Part2

上一篇文章中,我们建立了一个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 实例,让我们一起来看看它包含的属性:

  • minWidthmaxWidth:用来设置界面的大小,并且都默认值。在这个应用中,我们将创建一个大小为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
[ 转载请保留原文出处、译者和译文链接。]



相关文章

发表评论

Comment form

(*) 表示必填项

2 条评论

  1. leo 说道:

    good

    Thumb up 0 Thumb down 1

  2. 自信 说道:

    咱这个网站内容很好,不过推广不够好啊,知道的人太少了

    Thumb up 0 Thumb down 0

跳到底部
返回顶部