widget包是存放自定义组件

开发自定义组件;

其实Android API开发指南中的App Widgets章节 已经说得很清楚了,下面只是对自己的理解进行一次梳理。

-- 
AppWidget 就是HomeScreen上显示的小部件,提供直观的交互操作。通过在HomeScreen中长按,在弹出的对话框中选择Widget部件来进行创建,长按部件后并拖动到垃圾箱里进行删除。同一个Widget部件可以同时创建多个。

AppWidget的实现主要涉及到以下类: 
AppWidgetProvider 
RemoteViews 
AppWidgetManager

1. 
首先需要提供一个定义了Widget界面布局的XML文件(位于res/layout/..),需要注意的是使用的组件必须是RemoteViews所支持的,目前原生API中支持的组件如下: 
FrameLayout 
LinearLayout 
RelativeLayout

AnalogClock 
Button 
Chronmeter 
ImageButton 
ImageView 
ProgressBar 
TextView

*如果使用了除此之外的组件,则在Widget创建时会导致android.view.InflateExceptionn异常。

PS:这就导致有一些功能或样式无法实现,如很基本的list或文本编辑框都是无法直接实现的。如果想自定义Widget中的View的话只能通过修改framework来提供相应组件的支持。

2. 
然后需要提供一个xml文件来定义Widget的基本属性,放置到res/xml/..目录下。 
如果使用的是Eclipse可按如下操作: 
1) 在res/目录下创建xml/目录 
2)创建xml文件(名字可任意),选择类型为AppWidgetProvider 
3)在弹出的便捷界面进行参数设置

主要设置的参数如下: 
minWidth: 定义Wdiget组件的宽度 
minHeight: 定义Wdiget组件的高度 
updatePeriodMillis: 更新的时间周期 
initialLayout: Widget的布局文件 
configure: 如果需要在启动前先启动一个Activity进行设置,在这里给出Activity的完整类名(后面会说到,与一般Activity的实现有些许差别)

*Widget大小的计算单元格数*74)-2,API上说是为了防止像素计算时的整数舍入导致错所以-2...不是很明白

一个完整的样例: 
Xml代码  收藏代码

<?xml version="1.0" encoding="utf-8"?>  
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"  
          android:minWidth="80dp"  
          android:minHeight="32dp"  
          android:updatePeriodMillis="86400000"  
          android:initialLayout="@layout/widget_provider"  
          android:configure="com.demo.widget.MyWidgetConfiguration" >  
    </appwidget-provider>

3. 
xml都定义好后,接下来就是创建一个继承自AppWidgetProvider的子类,AppWidgetProvider实际上就是一个BroadcastReceiver,里面提供了以下函数: 
onReceive(Context, Intent) 
onUpdate(Context , AppWidgetManager, int[] appWidgetIds) 
onEnabled(Context) 
onDeleted(Context, int[] appWidgetIds) 
onDisabled(Context) 
可通过重写以上函数来监听Widget状态的变化并进行相应的处理。

以上函数具体调用情况归纳如下: 
[启动 - 无confiure Activity] 
onReceive 
onEnabled —— 第一个widget被显示 
onReceive 
onUpdate —— 刷新界面

[启动 - 带confiuration Activity] 
onReceive 
onUpdate

[拖动] 
<无状态变化>

[周期更新] 
onReceive 
onUpdate

[删除] 
onReceive 
onDeleted —— widget被删除 
onReceive 
onDisabled —— 最后一个widget被移除

[启动时位置不够] 
onReceive 
onEnabled 
onReceive 
onUpdate 
onReceive 
onDeleted 
onReceive 
onDisabled

*每次状态的变化会触发onReceive,一般该函数是不需要重写的。

简单了解AppWidgetProvider之后,我们来看具体实现。 
这里创建一个MyAppWidgetProvider继承AppWidgetProvider: 
Java代码  收藏代码

public class MyWidgetProvider extends AppWidgetProvider {  
      
          static final String TAG = "widget";  
           
          /** 
           * 更新 
           */  
          public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){  
                Log.i(TAG, "onUpdate");  
          }  
           
          /** 
           * 第一个Widget组件启动时触发 
           */  
          public void onEnabled(Context context){  
                Log.i(TAG, "onEnabled");  
          }  
           
          /** 
           * 最后一个Widget组件关闭时触发 
           */  
          public void onDisabled(Context context){  
                Log.i(TAG, "onDisabled");  
          }  
           
          /** 
           * 任一Widget组件被删除时触发 
           */  
          public void onDeleted(Context context, int[] appWidgetIds){  
                Log.i(TAG, "onDeleted");  
          }  
           
          /** 
           * 以上函数触发前会先触发该函数,一般不需要重写 
           */  
          public void onReceive(Context context, Intent intent){  
                Log.i(TAG, "onReceive");  
                super.onReceive(context, intent);  
          }  
           
    }

其中onUpdate顾名思义是对Widget进行更新的,前面定义的更新周期就是作用于该函数的。 
Widget的更新与Activity不同,必须借助于RemoteViews和AppWidgetMananger。具体实现如下: 
Java代码  收藏代码

public void onUpdate(Context context, AppWidgetMananger appWidgetManager, int[] appWidgetIds){  
        int N = appWidgetIds.length; // 可能启动了多个Widget,appWidgetIds记录了这些Widget的ID  
        for(int i=0; i<N; i++){  
            RemoteViews  views = new RemoteViews(getPackageName(), R.layout.widget_views);  
            appWidgetManager.updateAppWidget(appWidgetIds[i], views);  
        }  
    }

其中需要注意的是,虽然RemoteViews参数都是一样的,但是对于每个Widget最好都新创建一个再进行传递,否则会导致一些错误。具体可参考AppWidget RemoteViews 内存溢出 。

其他函数的可以根据需要实现。

由于无法获取到RemoteViews创建的界面中的元素,对于Widget中组件的操作只能通过RemoteViews所提供的有限的函数进行,常用的有: 
setOnClickPendingIntent(int viewId, PendingIntent pendingIntent) 
setProgressBar(int viewId, int max, int progress, boolean indeterminate) 
setTextViewText(int viewId, CharSequence text) 
setViewVisibility(int viewId, int visibility) 
详细函数列表可参考API中的RemoteViews类 。

4. 
最后,更新AndroidManifest.xml。 
AppWidgetProvider对应一个receiver属性: 
Xml代码  收藏代码

<receiver android:name="MyWidgetProvider">  
                <intent-filter>  
                    <action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>  
                </intent-filter>  
                <meta-data android:resource="@xml/widget_property" android:name="android.appwidget.provider"></meta-data>  
            </receiver>

5. 
提供Configuration Activity 
Configuration Activity是一个在Widget启动前先启动的Activity,方便用户对Widget的属性进行设置。

在res/xml/...下对应的"属性文件"中添加configure字段指定启动的Activity,并在AndroidManifest.xml中该Activity下提供一个action为android.appwidget.action.APPWIDGET_CONFIGURE 的IntenFilter。

需要注意的是, 
如果设置了Configure属性,则必须在指定的Activity中进行如下处理: 
1.在onCreate中setContentView()函数前添加setResult(RESULT_CANCLE) ,这样如果在Activity初始化完成前按下了BACK按键,则Widget不会启动; 
2.在setContentView()函数之后(不一定要在onCreate中,在Activity退出前即可),添加如下设置以指定需要启动的Widget: 
Java代码  收藏代码

int mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);  
    Intent resultValue = new Intent();  
    resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);  
    setResult(RESULT_OK, resultValue);

否则会导致退出Activity后Widget不启动。

>> Widget创建步骤汇总: 
1.定义Widget布局XML -> res/layout/... 
2.定义Widget属性文件(xml) -> res/xml/... 
3. 创建AppWidgetProider子类,实现onUpdate()等函数,在manifest中注册receiver,添加一个action为 android.appwidget.action.APPWIDGET_UPDATE 的IntentFilter,并添加如下<meta- data>标识: 
Xml代码  收藏代码

<meta-data android:resource="@xml/<属性文件xml>" android:name="android.appwidget.provider"></meta-data>

4. 创建Coniguration Activity(注意处理好setResult),添加到属性文件中的Configure属性,在manifest中注册activity,添加一个 action为android.appwidget.action.APPWIDGET_CONFIGURE 的IntentFilter

最后附上一个完整的例子, 
实现思路如下: 
1. 提供一个Configuration Activity,这里只简单显示一行文字; 
2.退出后Widget启动; 
3.点击Widget中的按钮会启动一个Activity

(转自:http://quding0308.iteye.com/blog/1164276)

android widget包说明与应用的更多相关文章

  1. android widget 开发实例 : 桌面便签程序的实现具体解释和源代码 (上)

    如有错漏请不吝拍砖指正,转载请注明出处,很感谢 桌面便签软件是android上经常使用软件的一种,比方比較早的Sticky Note,就曾很流行, Sticky Note的介绍能够參见 http:// ...

  2. Android Widget(窗口小部件)

    Android Widget简介 应用程序窗口小部件(Widget)是微型的应用程序视图,它可以被嵌入到其它应用程序中(比如桌面)并接收周期性的更新.你可以通过一个App Widget Provide ...

  3. Android Widget小组件开发(一)——Android实现时钟Widget组件的步骤开发,这些知识也是必不可少的!

    Android Widget小组件开发(一)--Android实现时钟Widget组件的步骤开发,这些知识也是必不可少的! PS:学习自某网站(不打广告) 这个小组件相信大家都很熟悉吧,以前的墨迹天气 ...

  4. java.lang.ClassCastException android.widget.RelativeLayout LayoutParams 异常

    1.在xml布局文件如下所示: <RelativeLayout android:layout_width="match_parent" android:layout_heig ...

  5. Android Java包各种功能简述

    开发Android应用程序基本上使用的都是Java语言. 那么要想灵活的应用这一系统,就应当熟悉当中的Android Java包的各种功能. 一般的JAVA应用中.假设需用引用基础类库,通常须要使用例 ...

  6. Android通过包名打开第三方应用

    import android.content.ComponentName; import android.content.Context; import android.content.Intent; ...

  7. Android导包导致java.lang.NoClassDefFoundError

    摘要: SDK方法总数是不能超过65k的.是否也引入其他的三方库,导致总数超过限制.超出限制会导致部分class找不到,引发java.lang.NoClassDefFoundError.解决方法:近日 ...

  8. 关于java.lang.NoSuchMethodError: android.widget.RelativeLayout.setBackground的解决办法

    今天用一个安卓4.0.4版本的手机测试手上的项目,发现logcat弹出这样一个提示“java.lang.NoSuchMethodError: android.widget.RelativeLayout ...

  9. 关于iOS和android自定义包的名字

    自定义包名的使用,android的包名和ios的包名都是你的自定义包名!如下以新浪微博SDK自定义包名示例:(官方没的,自己踩过坑,方便后来人吧) 相关技术文档:http://www.apicloud ...

随机推荐

  1. iOS AFNetworking 打印从服务器返回的错误提示信息

    每次做项目的时候都会在网络请求时候测试接口的时候会出现一些不同的错误,而控制台打印的错误提示信息都是data类型,看不出提示的错误的信息是什么.后面经过一些查阅发现其实是可以把这个转变为string的 ...

  2. windows / linux系统中,端口被占用解决方法

    一.在windows操作系统中,查询端口占用和清除端口占用的程序 提升权限后用:netstat -b或用 1.查询端口占用的进程ID 点击"开始"-->"运行&qu ...

  3. Hibernate关联映射(单项多对一和一对多、双向一对多)

    最近总是接触着新的知识点来扩展自己的知识面:不停的让自己在原地接触天空的感觉真的很美好!!!革命没有成功,程序员的我们怎么能不努力呢...... 一.用员工和部门来剖析关联映射的原理. 1)从这张截图 ...

  4. MyBank(自助银行)系统

    光阴似箭,岁月如梭. 从开始学Java到现在学C#已快四个月了,我们学的东西越来越多了.但是虽说学到现在,都不知道有什么用?没地方表现啊. 那么今天我就来给大家说说说这些东西的用处吧. 就拿MyBan ...

  5. 钉钉客户端JS-API权限签名算法.NET版

    前段时间写了一篇博文<钉钉如何进行PC端开发>,在里面并未解决本地生成签名的问题,需要到官网进行生成,由于钉钉门票等认证信息会超期,因此,必须能本地用代码自动更新相关参数信息,来换取签名. ...

  6. 你应该知道的10个奇特的 HTML5 单页网站

    网页设计师努力寻找新的方式来展现内容.其中一个大的趋势是单页网站,现在被世界上的一些大的品牌广泛采用,使用它们来为用户提供一个快速,干净和简单的而且​​美丽的网站. 下面是10个令人惊叹的单页 H​​ ...

  7. [js开源组件开发]localStorage-cache本地存储的缓存管理

    localStorage-cache本地存储的缓存管理 距离上次的组件开发有近三个月的时间了,最近一直在做一些杂事,无法静下心来写写代码,也是在学习emberjs,在emberjs中有一个很重要的东西 ...

  8. [deviceone开发]-企业OA项目开源分享

    一.简介 是一个真实的企业OA项目改造的开源项目,几乎涵盖了所有常用的组件,包括环信实现在线聊天等功能,类似微信的朋友圈功能,自定义的智能搜索等,而且这个是真实的通过Http链接后台web服务,里面很 ...

  9. clang编译mysql(Ubuntu10 64位)

    编译安装mysql(Ubuntu10 64位) http://www.cnblogs.com/2018/p/3482259.html 这个介绍了gcc形式编译安装mysql 那我们使用clang进行编 ...

  10. SharePoint 2013 – Workflow Manager 1.0 offline download

    [http://sharepointdeal.wordpress.com/2013/03/13/sharepoint-2013-workflow-manager-1-0-offline-downloa ...