桌面widget详解(一)——基本demo构建

桌面widget详解(一)——基本demo构建,第1张

概述一、概述App Widget是应用程序窗口小部件(Widget)是微型的应用程序视图,它可以被嵌入到其它应用程序中(比如桌面)并接收周期性的更新。你可以通过一个App Widget Provider来发布一个Widget。官方文档地址:《App Widgets》这里涉及到两个方面的内容:AppWidgetProvider类和appwidget-provider标签;1、appwid... 一、概述

App Widget是应用程序窗口小部件(Widget)是微型的应用程序视图,它可以被嵌入到其它应用程序中(比如桌面)并接收周期性的更新。你可以通过一个App Widget ProvIDer来发布一个Widget。官方文档地址:《App Widgets》

这里涉及到两个方面的内容:appwidgetprovider类和appWidget-provIDer标签;
 

1、appWidget-provIDer标签:

这个玩意是用来定义桌面Widget的大小,初始状态等等信息的,它的位置应该放在res/xml文件夹下,具体的xml参数如下:

androID:minWIDth : 最小宽度androID:minHeight : 最小高度androID:updatePeriodMillis : 更新Widget的时间间隔(ms),"86400000"为1个小时androID:prevIEwImage : 预览图片androID:initialLayout : 加载到桌面时对应的布局文件androID:resizeMode : Widget可以被拉伸的方向。horizontal表示可以水平拉伸,vertical表示可以竖直拉伸androID:Widgetcategory : Widget可以被显示的位置。home_screen表示可以将Widget添加到桌面,keyguard表示Widget可以被添加到锁屏界面。androID:initialKeyguardLayout : 加载到锁屏界面时对应的布局文件
 

至于具体怎么用,等下实战的时候会讲。

 

2、appwidgetprovider类:

上面我们通过appWidget-provIDer标签就可以得到初始化的布局,视图等,但我们的Widget要实时更新怎么办,要响应用户 *** 作怎么办,这就需要额外的类来辅助处理了,这个类就是appwidgetprovider。

由于appwidgetprovider要接收到当前Widget的状态(是否被添加,是否被删除等),所以要接收通知,必然是派生自broadcastReceiver。
 

appwidgetprovider中的广播处理函数如下:(根据不同的使用情况,重写不同的函数)

onUpdate():

在3种情况下会调用OnUpdate()。onUpdate()是在main线程中进行,因此如果处理需要花费时间多于10秒,处理应在service中完成。(第二篇会讲为什么还要有service)
(1)在时间间隔到时调用,时间间隔在Widget定义的androID:updatePeriodMillis中设置;
(2)用户拖拽到主页,Widget实例生成。无论有没有设置Configure activity,我们在AndroID4.4的测试中,当用户拖拽图片至主页时,Widget实例生成,会触发onUpdate(),然后再显示activity(如果有)。这点和资料说的不一样,资料认为如果设置了Configure acitivity,就不会在一开始调用onUpdate(),而实验显示当实例生成(包括创建和重启时恢复),都会先调用onUpate()。在本例,由于此时在preference尚未有相关数据,创建实例时不能有效进行数据设置。
(3)机器重启,实例在主页上显示,会再次调用onUpdate()
 

onDeleted(Context,int[]):

当 Widget 被删除时被触发。

onEnabled(Context):

当第1个 Widget 的实例被创建时触发。也就是说,如果用户对同一个 Widget 增加了两次(两个实例),那么onEnabled()只会在第一次增加Widget时触发。

onDisabled(Context):

当最后1个 Widget 的实例被删除时触发。

onReceive(Context,Intent):

在接收到广播时,调用。

二、实战

先看一下显示效果:

就这么一个桌面Widget,一个音乐播放器,这一篇只是显示出来,后面我们会慢慢完善它的功能。

1、appWidget-provIDer及布局文件

前面我们讲过,appWidget-provIDer提供了桌面Widget的初始化显示状态、默认图标、大小等功能,但它必须放在res/xml文件夹下,看看这里的代码:

<appWidget-provIDer xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:initialLayout="@layout/example_appWidget"    androID:minHeight="60dp"    androID:minWIDth="180dp"    androID:prevIEwImage="@drawable/prevIEw"    androID:resizeMode="horizontal|vertical"    androID:Widgetcategory="home_screen|keyguard" > </appWidget-provIDer>

这里有几个参数:

 

prvIEwImage:就是添加桌面控件时,我们的控件在列表中的显示状态,如下图所示,下面这个丑娃娃就是我们的显示图标……

androID:initialLayout="@layout/example_appWidget":这个就是指定初始化显示时,应该显示的布局;

下面看看这个布局文件:example_appWidget.xml

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:background="#33000000"    androID:gravity="center"    androID:orIEntation="horizontal" >        <TextVIEw         androID:layout_wIDth="wrap_content"        androID:layout_height="wrap_content"        androID:layout_marginRight="8dip"        androID:background="@drawable/car_musiccard_up"/>        <TextVIEw         androID:layout_wIDth="wrap_content"        androID:layout_height="wrap_content"        androID:layout_marginRight="8dip"        androID:background="@drawable/car_musiccard_play"/>        <TextVIEw         androID:layout_wIDth="wrap_content"        androID:layout_height="wrap_content"        androID:background="@drawable/car_musiccard_down"/> </linearLayout>

这个布局就是最上头显示出来的那个播放器的布局。

2、Exampleappwidgetprovider extends appwidgetprovider

在布局成功之后,下面就是根据通知实现逻辑了,这篇我们只接收通知,逻辑下篇再说。首先新建一个类Exampleappwidgetprovider,将其派生自appwidgetprovider;然后就会有下面的代码:

public class Exampleappwidgetprovider extends appwidgetprovider { 	 /*	  * 在3种情况下会调用OnUpdate()。onUpdate()是在main线程中进行,因此如果处理需要花费时间多于10秒,处理应在service中完成。	  *(1)在时间间隔到时调用,时间间隔在Widget定义的androID:updatePeriodMillis中设置; 	  *(2)用户拖拽到主页,Widget实例生成。无论有没有设置Configure activity,我们在AndroID4.4的测试中,当用户拖拽图片至主页时,Widget实例生成,会触发onUpdate(),然后再显示activity(如果有)。这点和资料说的不一样,资料认为如果设置了Configure acitivity,就不会在一开始调用onUpdate(),而实验显示当实例生成(包括创建和重启时恢复),都会先调用onUpate()。在本例,由于此时在preference尚未有相关数据,创建实例时不能有效进行数据设置。	  *(3)机器重启,实例在主页上显示,会再次调用onUpdate()	  */ 	@OverrIDe	public voID onUpdate(Context context,AppWidgetManager appWidgetManager,int[] appWidgetIDs) { 		super.onUpdate(context,appWidgetManager,appWidgetIDs);	} 	// Widget被删除时调用	@OverrIDe	public voID onDeleted(Context context,int[] appWidgetIDs) {		Log.d(TAG,"onDeleted(): appWidgetIDs.length=" + appWidgetIDs.length); 		super.onDeleted(context,appWidgetIDs);	} 	// 最后一个Widget被删除时调用	@OverrIDe	public voID onDisabled(Context context) {		Log.d(TAG,"onDisabled"); 		super.onDisabled(context);	} 	// 第一个Widget被创建时调用	@OverrIDe	public voID onEnabled(Context context) { 		super.onEnabled(context);	} 	// 接收广播的回调函数	@OverrIDe	public voID onReceive(Context context,Intent intent) { 		super.onReceive(context,intent);	}}

这里不是继承接口,这几个函数并不是需要全部重写的,根据需要,要用到哪个可以重写哪个。

 

3、注册Exampleappwidgetprovider

前面我们讲到appwidgetprovider派生自broadcastReciver,所以要提前注册,有关broadcastReciver的注册有两种方法,静态注册和动态注册,因为这里要接收来自的消息,而且在程序启动时就开始自动监听,所以,这里需要静态注册。

<!-- 声明Widget对应的appwidgetprovider --><receiver androID:name=".Exampleappwidgetprovider" >    <intent-filter>	<action androID:name="androID.appWidget.action.APPWidget_UPDATE" />    </intent-filter>    <Meta-data androID:name="androID.appWidget.provIDer"	androID:resource="@xml/example_appWidget_info" /></receiver>

(1)接收的action定义为:"androID.appWidget.action.APPWidget_UPDATE"这表明接收系统发来的有关这个app的所有Widget的消息(主要是增加、删除)。

 

(2)<Meta-data> 指定了 appwidgetproviderInfo 对应的资源文件
androID:name -- 指定Metadata名,指定为androID.appWidget.provIDer表示这个data中的数据是appwidgetproviderInfo 类型的
androID:resource -- 指定 appwidgetproviderInfo 对应的资源路径。即,xml/example_appWidget_info.xml。

 

三、可能出现的错误:

1、有关布局错误

在构造Widget布局时,App Widget支持的布局和控件非常有限,有如下几个:

App Widget支持的布局:

  FrameLayout  linearLayout  relativeLayout  GrIDLayout

 App Widget支持的控件:

  AnalogClock  button              Chronometer  Imagebutton  ImageVIEw  Progressbar  TextVIEw  VIEwFlipper  ListVIEw  GrIDVIEw  StackVIEw  AdapterVIEwFlipper

除此之外的所有控件(包括自定义控件)都无法显示,无法显示时,添加出来的Widget会显示“加载布局出错”

2、appWidget-provIDer出现错误

如果appWidget-provIDer页面出现错误提示:error: No resource IDentifIEr found for attribute 'Widgetcategory' in package 

'androID'

这是由于build target应该在17以上,有两种方法解决:

方法1:找到工程中的project.propertIEs文件将target=androID-14改为target=androID-17   

方法2:工程上右键-》propertIEs  选择AndroID,将Project Build Target改为17或以上,如图:(改完之后rebuild一下工程)

总结

以上是内存溢出为你收集整理的桌面widget详解(一)——基本demo构建全部内容,希望文章能够帮你解决桌面widget详解(一)——基本demo构建所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1089428.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存