什么是Home Screen Widgets

Home screen Widget即称为小工具或者中文小工具,是显示在主页上的views,通过后台进程更新view的数据。

Android由AppWidgetManager来管理系统的widgets。安装apk后。会依据widget定义在widget列表中显示该Widget的名称、图标以及所占空间,在Android4.0中。以网格方式来显示,有些OEM厂商会对UI进行又一次设计,widget列表的展现形式会有所不同。

我们长按widget列表中的某个widget。将其拖拽到主页上。实际上是AppWidgetManager在主页上创建该widget的一个实例(instance)。

能够有多个实例,不同实例用widgetID来区分它们。

widget定义两个重要的java 类,一个是widget configurator activity。在widget实例生成时,被AppWidgetManager通过intent唤起进行初始化配置,当中action名为android.appwidget.action.APPWIDGET_CONFIGURE,这个java类是可选的,通常在此进行配置数据的输入和保存。因为数据量少。能够非常方便地保存在shared preference中。

假设我们创建了两个widget实例,这个配置activity会被调用两次。

一个Java类。负责管理widget的生命周期,包含当拖拽到主页时,须要更新时,以及拖入到垃圾桶时的处理。它是AppWidgetProvider的继承,本质是一个广播接收器,依据AppWidgetManager发出的广播信息。触发不同的回调函数,比如widget数据更新时间间隔(在widget定义中给出),widget实例的生成和删除。第一个widget实例的生成。最后一个widget实例的删除。

widget在页面上的生成是由AppWidgetManager依据我们在widget定义中给出的layout文件生成有关的UI。不是由我们的代码直接生成,因此我们也无法向在activity中那也直接对widget中的view进行操作,须要通过RemoteViews。提交给AppWidgetManager对某个实例进行处理。

小样例

我们将通过小样例。具体解读怎样创建一个widget。小样例是一个生日提醒器。

在生成widget实例时,弹出配置activity,在activity中输入名字和出生日期。按“设置”button将数据保存在preference中,并关闭activity。

widget最上的view显示widget_id:名字,中间左边显示距下一次生日的天数。点击右边的view可打开某个网页,以下显示出生日期。

定义广播接收器

前面提到Widget有两个重要的java类,一个是可选的用于配置的activity,一个用于管理wdiget生命周期的广播接收器,接收器接收AppWidgetManager的广播消息。来触发各类回调函数。

我们需在AndroidManifest.xml中定义这两个java类,以下给出广播接收器的类定义。

<manifest ……  > 

    <application …… android:label="TestWidget" ……> <!-- android:label就是widget列表中的widget名称 -->

        … … 

        <receiver android:name=".BirthDayWidgetProvider"> 

            <meta-data android:name="android.appwidget.provider" android:resource="@xml/birthday_widget_provider"/>

            <intent-filter> 

                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>

            </intent-filter>
 

        </receiver> 

    </application> 

</manifest>

这个类是继承android.appwidget.AppWidgetProvider,通过meta-data设置有关的參数。

这里补充一下meta-data的知识。最为常见的是採用键值对的方式,即<meta-data android:name="xxx" android:value="yyy" />,在组件中能够获得该数值,比如在activity中:

ActivityInfo actInfo = mContext.getPackageManager().getActivityInfo( getComponentName(), PackageManager.GET_META_DATA);  

String msg = actInfo.metaData.getString("activity_name");

而在service,则为ServiceInfo,在application中为ApplicationInfo。在receiver中为ActivityInfo,但用getReceiverInfo, 假设须要ComponentName參数,能够用 new ComponentName(context, MyComponent.class)来获取。

我们看看android.appwidget.AppWidgetManager.java的有关代码:

/** 

* Sent when it is time to update your AppWidget. 



This may be sent in response to a new instance for this AppWidget provider having

* been instantiated
, the requested {@link AppWidgetProviderInfo#updatePeriodMillis update interval} having lapsed, or the system booting.

* …… 



* @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)

*/ 

public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";



/**  

   * Field for the manifest meta-data tag.  

   *  

   * @see AppWidgetProviderInfo  

   */  

public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";

在meta-data中,android.appwidget.provider为Android指定的keyword。用于在相应的resource中定义App Widget Provider信息的文件。该文件位于xml/下。本样例为res/xml/birthday_widget_provider.xml,定义widget的參数。

android.appwdiget.action.APPWIDGET_UPDATE是接收器监听AppWidgetManger的广播消息之中的一个。其它还监听ACTION_APPWIDGET_ENABLED等等消息。但在receiver中必须指明是ACTION_APPWIDGET_UPDATE,系统才可识别出接收器实际是widget,才干在widget列表中加入该widget。其它须要监听的消息无需在此列出。

App widget provider的定义

在manifest.xml中。通过meta-data给出appwidget provider定义所在文件为xml/birthday_width_provider.xml,内容例如以下。

<?

xml version="1.0" encoding="utf-8"?



<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"

    android:minWidth="150dp" 

    android:minHeight="120dp" 

    android:updatePeriodMillis="43200000" 

    android:initialLayout="@layout/birday_widget" 

    android:configure="cn.wei.flowingflying.testwidget.ConfigBirthDayWidgetActivity"   

    android:previewImage="@drawable/gift" 

    android:resizeMode="horizontal|vertical"> 

</appwidget-provider>

在widget列表中显示widget的大小为3×2。

在xml中。我们定义长150dp,宽120dp,实际上widget在Home Screen占领的空间是按网格计算的。每一个网格为74dp×74dp,系统会分配所需容纳的网格。一般手机网格为4×4,平板为8×7。

在《Pro Android》一书中给出建议为74的N倍减去2dp(适配边框),而在Android开发人员站点推荐定义的min长宽为70*N-30。以下是给出的一个样例:

本例间隔时间为12小时(43200000ms)。

Android强烈建议1天最多仅仅有几次,不要太多。

从Android2.0開始,最小值为30分钟。

假设我们设置为0。表示不会自己主动update,我们能够通过AlarmManager类来自行控制何时update。

作为实验小样例。能够改为1小时,但不能设置太短,比如1分钟,在模拟器的实验中,假设时间间隔太短是不会进行触发的。

从SDK3.1開始。用户长按widget,可以resize widget。包含horizontal,vertical和none。要可以resize,要求layout參数可伸缩,注意。假设size改变是没有callback提醒的。

详细怎样resize不太明白。

previewImage是在widget list的图标,假设没有这项,有用manifest文件里定义的main icon。widget列表中的显示也称为preview。

配置Activity的定义

在appwidget-provider中通过android:configure定义配置的java类ConfigBirthDayWidgetActivity,这是个普通的activity,须要在AndroidManifest.xml中进行说明,并支持响应APPWIDGET_CONFIGURE action。AndroidManifest.xml的代码片段例如以下:

<activity android:name=".ConfigBirthDayWidgetActivity" android:label="配置生日小工具"> 

    <intent-filter> 

        <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>

    </intent-filter> 

</activity>

至此。我们完毕了widget的定义。即使我们没有详细编写不论什么的java类代码,我们仍能够将其打包,并在设备上安装。安装后在widget列表中看到我们的小样例TestWidget。

Widget的外观定义

在appwidget-provider中通过android:initialLayout定义widget的外观。对应的layout/birday_widget.xml例如以下:

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 

    android:layout_width="150dp" 

    android:layout_height="120dp" 

    android:orientation="vertical" 

    android:background="@drawable/box1"> 

    <TextView android:id="@+id/bd_name" 

        android:layout_width="match_parent" 

        android:layout_height="30dp" 

        android:text="Anonymous" 

        android:background="@drawable/box1" 

        android:gravity="center"/> 

    <LinearLayout android:orientation="horizontal" 

        android:layout_width="match_parent" 

        android:layout_height="60dp"> 

        <TextView android:id="@+id/bd_days" 

            android:layout_width="wrap_content" 

            android:layout_height="match_parent" 

            android:text="0" 

            android:gravity="center" 

            android:textSize="30sp" 

            android:layout_weight="50"/> 

        <TextView android:id="@+id/bd_buy" 

            android:layout_width="wrap_content" 

            android:layout_height="match_parent" 

            android:textSize="20sp" 

            android:text="Buy" 

            android:layout_weight="50" 

            android:background="#FF6633" 

            android:gravity="center"/> 

    </LinearLayout> 

    <TextView android:id="@+id/bd_date" 

        android:layout_width="match_parent" 

        android:layout_height="30dp" 

        android:text="2000/1/1" 

        android:background="@drawable/box1" 

        android:gravity="center"/>" 

</LinearLayout>

和activity不同。不能直接在代码中获取view的对象并进行控制。须要通过AppWidgetManager用RemoteViews来进行间接控制。

因此在widget外观定义中,view须要能支持remote view,包含FrameLayout、LinearLayout、RelativeLayout、AnalogClock、Button、Chronometer、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView、AdapterViewFlipper。

Android给出widget外观设计的guideline,见http://developer.android.com/guide/practices/ui_guidelines/widget_design.html

通过android:background="@drawable/box1",能够定义外围轮廓。

res/drawable/box1.xml的内容例如以下:

<?xml version="1.0" encoding="utf-8"?



<shape xmlns:android="http://schemas.android.com/apk/res/android" > 

    <stroke android:width="4dp" android:color="#888888"/>  <!--定义边框 --> 

    <padding android:left="2dp" android:top="2dp" android:right="2dp" android:bottom="2dp"/>

    <corners android:radius="4dp" /> 

</shape>

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Android学习笔记:Home Screen Widgets(1):大约Widget的更多相关文章

  1. Pro Android学习笔记(一三七):Home Screen Widgets(3):配置Activity

    文章转载仅仅能用于非商业性质,且不能带有虚拟货币.积分.注冊等附加条件.转载须注明出处http://blog.csdn.net/flowingflying/以及作者@恺风Wei. 通过widget定义 ...

  2. Android学习笔记:Home Screen Widgets(2):关于Widget

    通过widget定义,我们在widget列表中看到了我们的TestWidget.当我们拖拽widget到主页时,假设在appwidet-provider中定义了android:configure的ja ...

  3. 【转】 Pro Android学习笔记(五七):Preferences(1):ListPreference

    目录(?)[-] 例子1ListPreference小例子 定义一个preferences XML文件 继承PreferenceActivity 用户定制偏好的读取 第一次运行时设置缺省值 设置Cat ...

  4. 【转】Pro Android学习笔记(四):了解Android资源(下)

    处理任意的XML文件 自定义的xml文件放置在res/xml/下,可以通过R.xml.file_name来获取一个XMLResourceParser对象.下面是xml文件的例子: <rootna ...

  5. 【转】Pro Android学习笔记(三):了解Android资源(上)

    在Android开发中,资源包括文件或者值,它们和执行应用捆绑,无需在源代码中写死,因此我们可以改变或替换他们,而无需对应用重新编译. 了解资源构成 参考阅读Android学习笔记(三八):资源res ...

  6. Android 学习笔记之Volley(七)实现Json数据加载和解析...

    学习内容: 1.使用Volley实现异步加载Json数据...   Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...

  7. Android学习笔记进阶之在图片上涂鸦(能清屏)

    Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...

  8. android学习笔记36——使用原始XML文件

    XML文件 android中使用XML文件,需要开发者手动创建res/xml文件夹. 实例如下: book.xml==> <?xml version="1.0" enc ...

  9. Android学习笔记之JSON数据解析

    转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...

  10. udacity android 学习笔记: lesson 4 part b

    udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

随机推荐

  1. 第二章 自己的框架WMTS服务,下载数据集成的文章1

    在构建数据源下载文件的叙述性说明第一步 如此XML结构体 <?xml version="1.0" encoding="utf-8"?> <on ...

  2. 移动端 new CustomEvent('input') 兼容问题

    最近在 安卓自带浏览器 上发现  new CustomEvent('input') 不兼容 解决办法 (function () { if(!!window.CustomEvent) return; f ...

  3. hdu 3081 hdu 3277 hdu 3416 Marriage Match II III IV //灵活运用最大流量

    3081 意甲冠军: n女生选择不吵架,他甚至男孩边(他的朋友也算.并为您收集过程).2二分图,一些副作用,有几个追求完美搭配(每场比赛没有重复的每一个点的比赛) 后.每次增广一单位,(一次完美匹配) ...

  4. 找呀志_ContentResolver操作ContentProvider数据

    当需要外部的应用ContentProvider该数据被添加.删.修改和查询操作.可以使用ContentResolver 类完成 要得到ContentResolver 物,可以使用Activity提供g ...

  5. 基于VMware的虚拟Linux集群搭建-lvs+keepalived

    基于VMware的虚拟Linux集群搭建-lvs+keepalived 本文通过keepalived实现lvsserver的的双机热备和真实server之间的负载均衡.这方面的blog挺多,可是每一个 ...

  6. 跑ssis分组差错:没有关联“”。假设无法找到一个特定的连接元件,Connections 这种错误发生的收集

    跑ssis分组差错:没有关联"".假设无法找到一个特定的连接元件,Connections 这种错误发生的收集. 在网上搜了一下,解决方法: 打开SqlServer Configur ...

  7. Sql Server存储过程和函数浅谈

    今天给大家总结一下sql server中的存储过程和函数.本人是小白,里面内容比较初级,大神不喜勿喷 自行飘过就是.. 首先给大家简单列出sql server中的流控制语句,后面会用到的^_^ sql ...

  8. XML概要

     早在两年前,我一直听说XML,但是,只是没有时间去研究它.也不知道它的作用,花了一些时间最近几天来学习他们的语言.是XML的一些简介希望能对各位同学有所帮助: XML是eXtensible Ma ...

  9. Xcode-5.1.1更改文件盯作者

    原来的文件默认是用户开机时的username ,网上说什么改通讯录事实上都是不正确的. 1.首先打开偏好设置,选择用户群组 2.进入用户界面 改动全名.此时要求你输入用户的password才干改动us ...

  10. interview(转)

    http://ifeve.com/ali-think-12/ http://ifeve.com/think-in-ali-10/