什么是AppWidget?AppWidget就是我们平常在桌面上见到的那种一个个的小窗口,利用这个小窗口可以给用户提供一些方便快捷的操作。

今天的目标就是怎么创建一个简单的AppWidget。


首先我先把目录结构展示一下,方便大家理解。


第一步:我们需要在res目录下创建一个folder,可以命名为xml(但这并不是必须的,你也可以换成你喜欢的名字)。然后在这么目录下创建一个xml文件。我的appwidget.xml文件代码如下:

  1. <appwidget-provider
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:minHeight="72dp"
  4. android:minWidth="294dp"
  5. android:updatePeriodMillis="86400000"
  6. android:initialLayout="@layout/example_widget"
  7. >
  8. </appwidget-provider>

小注解:


在android的命名空间下声明了appwidget 的最小的高度、宽度、以及更新的时间(注意是以毫秒为单位的)和最重要的绑定的布局文件(所谓布局文件就是展示到桌面上的界面的外观)。


第二步:下面的这个文件是在上面的appwidget.xml中的initialLayout属性中绑定的xml布局文件,即example_widget.xml,代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:id="@+id/textview1"
  8. android:layout_width="match_parent"
  9. android:layout_height="wrap_content"
  10. android:text="MyFirst Widget Example!"
  11. >
  12. </TextView>
  13. <!--由于只是实现简单的效果,所以就只用一个TextView吧-->
  14. </LinearLayout>

第三步:实现了布局展示界面,下面自然而然的,我们就会想到要怎么让这个布局界面展示出来,所以就必须有一个provider,因此,下面就需要创建一个继承了AppWidgetProvider的实例,来完成这一个功能。我的文件名称命名为Widget.java.

  1. package com.summer.widgettest;
  2. import android.appwidget.AppWidgetManager;
  3. import android.appwidget.AppWidgetProvider;
  4. import android.content.Context;
  5. /**
  6. *在这四个必须的方法中,只是打印出一句话,来观察其“生命周期”即可
  7. */
  8. public class Widget extends AppWidgetProvider {
  9. @Override
  10. public void onUpdate(Context context, AppWidgetManager appWidgetManager,
  11. int[] appWidgetIds) {
  12. // TODO Auto-generated method stub
  13. System.out.println("onUpdate");
  14. super.onUpdate(context, appWidgetManager, appWidgetIds);
  15. }
  16. @Override
  17. public void onDeleted(Context context, int[] appWidgetIds) {
  18. // TODO Auto-generated method stub
  19. System.out.println("onDeleted");
  20. super.onDeleted(context, appWidgetIds);
  21. }
  22. @Override
  23. public void onDisabled(Context context) {
  24. // TODO Auto-generated method stub
  25. System.out.println("onDisabled");
  26. super.onDisabled(context);
  27. }
  28. @Override
  29. public void onEnabled(Context context) {
  30. // TODO Auto-generated method stub
  31. System.out.println("onEnabled");
  32. super.onEnabled(context);
  33. }
  34. }

第四步:这也是最为关键的一步,因为前面的工作都是为这一步来打基础的。那么要怎么做捏?答案就是清单文件,在清单文件中进行声明就可以了。我的代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.summer.widgettest"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6. <uses-sdk
  7. android:minSdkVersion="8"
  8. android:targetSdkVersion="18" />
  9. <application
  10. android:allowBackup="true"
  11. android:icon="@drawable/ic_launcher"
  12. android:label="@string/app_name"
  13. android:theme="@style/AppTheme" >
  14. <activity
  15. android:name="com.summer.widgettest.MainActivity"
  16. android:label="@string/app_name" >
  17. <intent-filter>
  18. <action android:name="android.intent.action.MAIN" />
  19. <category android:name="android.intent.category.LAUNCHER" />
  20. </intent-filter>
  21. </activity>
  22. <receiver android:name="com.summer.widgettest.Widget">
  23. <intent-filter >
  24. <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
  25. </intent-filter>
  26. <meta-data android:name="android.appwidget.provider"
  27. android:resource="@xml/appwidget_info"/>
  28. </receiver>
  29. </application>
  30. </manifest>

小注解:

在这里我么也不难看出,原来widget也就是个广播事件啊,所以需要使用receiver ,然后接下来是一个inent-filter过滤器,功能就是过滤出符合要求的action,在这里当然是widget动作了。

接下来有一个meta-data元数据解释,作用就是对这个widget进行解释的作用,也是为了让android系统知道这到底是个什么东西。(偷偷告诉你,一般这两个要点是固定的表达)


好了,万事具备,只欠”运行“了,接下来就是程序运行之后的界面。。上面的那一行文字就是程序运行之后就可以看到的结果,也就是我们”自制“的一个AppWidget了。(说实话,真的是不太好看)。


回顾与总结:

1、怎么实现的这个AppWidget?先是在res文件夹下创建一个xml 文件夹,并在里面添加一个appwidget-provider文件,再就是写一个用于呈现内容的布局文件。接下来就是一个继承自AppWidgetProvider的类的创建,然后再清单文件中进行相关项的声明就可以了。

2、逻辑思路很重要,每一步的衔接是思路的引导点。

3、这里仅仅是一个简单的小例子,接下来要做的就是如何让这个widget和我们的系统进行交互。

4、好了,大致就是这样,欢迎广大博友留言评论,我一定会虚心的接受,希望能和你们一起进步!


—————————–这里是华丽的分界线——————


上面的是创建一个简单的appWidget的示例,下面是关于如何实现这些Widget如何实现相关的动作侦听的。

知识点准备:

我们应该知道的是,android的widget的进程与程序运行的进程并不是同一个进程,这就意味着我们不能像往常一样简单的使用一个setOnClickListener方法了,因为这样做是完不成相关的动作的侦听的功能的。那么问题来了,我们要怎么实现这些动作的交互呢?

别着急,答案是采用RemoteViews,顾名思义就是采用”远程的“方式来实现相关的处理操作。接下来让我们一起来看一下具体的实现流程吧。


第一步,在之前的appWidget的布局文件中添加一个按钮,用来实现布局。

  1. <Button
  2. android:id="@+id/button1"
  3. android:layout_width="match_parent"
  4. android:layout_height="wrap_content"
  5. android:text="Click To Renew!"
  6. >
  7. </Button>

第二步:然后再Widget.java这个AppWidgetProvider的实现类的onUpdate方法中实现相关的代码。为了更好地展示效果,我们可以新建一个Activity,用来呈现点击按钮之后跳转的界面的展示。我命名为RenewActivity.java.相关源码如下所示

  1. @Override
  2. public void onUpdate(Context context, AppWidgetManager appWidgetManager,
  3. int[] appWidgetIds) {
  4. // TODO Auto-generated method stub
  5. System.out.println("onUpdate");
  6. for(int i=0;i<appWidgetIds.length;i++){
  7. //check which appwidget is enabled!
  8. System.out.println(appWidgetIds[i]);
  9. Intent intent=new Intent(context,RenewActivity.class);
  10. PendingIntent pendingIntent=PendingIntent.getActivity(context, 0, intent, 0);
  11. RemoteViews remoteViews=new RemoteViews(context.getPackageName(), R.layout.example_widget);
  12. remoteViews.setOnClickPendingIntent(R.id.button1, pendingIntent);
  13. appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
  14. }
  15. super.onUpdate(context, appWidgetManager, appWidgetIds);
  16. }

RenewActivity.java

  1. package com.summer.widgettest;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. public class RenewActivity extends Activity{
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. // TODO Auto-generated method stub
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.renew);
  10. }
  11. //由于renew布局是一个非常简单的界面(一个TextView而已),所以不再贴出代码
  12. }

第三步:不要忘记在清单文件中进行Activity的声明,否则你是看不到界面的效果的。

  1. <activity
  2. android:name="com.summer.widgettest.RenewActivity"
  3. android:label="Renew Activity!"
  4. >
  5. </activity>

效果图如下所示:




小总结:

在Widget的onUpdate方法中,我们使用到了RemoteViews类的实例,起作用就不再详细的阐述,这里就直接解释代码的功能吧。如上,创建其实例的时候需要两个参数分别为上下文对象的包名和widget的”布局“,然后在进行对按钮的时间侦听的时候使用到了一个叫pendingIntent的实例,其作用就是将远程的消息信息传达给相应的处理逻辑中,进而实现对widget上按钮的动作的侦听处理。然后使用appWidgetManager进行更新操作就可以了!如此便可以完成我们的代码的逻辑。

Android学习笔记之AppWidget的更多相关文章

  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. Android 学习笔记之Volley(七)实现Json数据加载和解析...

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

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

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

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

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

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

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

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

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

  8. Android学习笔记36:使用SQLite方式存储数据

    在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...

  9. Android学习笔记之Activity详解

    1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...

随机推荐

  1. [Java] 设计模式:代码形状 - lambda表达式的一个应用

    [Java] 设计模式:代码形状 - lambda表达式的一个应用 Code Shape 模式 这里介绍一个模式:Code Shape.没听过,不要紧,我刚刚才起的名字. 作用 在应用程序的开发中,我 ...

  2. 一口一口吃掉Hibernate(六)——多对多关联映射

    今天来说说hibernate中的多对多关联映射,多对多关联映射涉及到单向映射和双向映射2种. 首先举个多对多关联例子:用户User和角色Role,一个用户可以属于多个角色,一个角色可以有多个用户.这就 ...

  3. 保留键的情况下取字典中最大的值(max\zip函数的联合使用)

    在我们平常想要获取字典中value最大或者最小的值的时候,常常使用如下函数: testDict = {"age1":18,"age2":20,"age ...

  4. 剑指架构师系列-Redis集群部署

    初步搭建Redis集群 克隆已经安装Redis的虚拟机,我们使用这两个虚拟机中的Redis来搭建集群. master:192.168.2.129 端口:7001 slave:192.168.2.132 ...

  5. delphi 线程教学第五节:多个线程同时执行相同的任务

    第五节:多个线程同时执行相同的任务   1.锁   设,有一个房间 X ,X为全局变量,它有两个函数  X.Lock 与 X.UnLock; 有如下代码:   X.Lock;      访问资源 P; ...

  6. Docker如何获取镜像

    可以使用 docker pull 命令来从仓库获取所需要的镜像. 下面的例子将从 Docker Hub 仓库下载一个 Ubuntu 12.04 操作系统的镜像. $ sudo docker pull ...

  7. Linux文件编辑命令详细整理

    刚接触Linux,前几天申请了个免费体验的阿里云服务器,选择的是Ubuntu系统,配置jdk环境变量的时候需要编辑文件. vi命令编辑文件,百度了一下,很多回答不是很全面,因此编辑文件话了一些时间. ...

  8. SQL批处理与事务控制

    今天我想要分享的是关于数据库的批处理与事务的控制.批处理对于项目的实际应用有非常大的具体意义. 一.批处理部分 首先我们新建一个表: create table t3( id int primary k ...

  9. 如果用一个循环数组q[0..m-1]表示队列时,该队列只有一个队列头指针front,不设队列尾指针rear,求这个队列中从队列投到队列尾的元素个数(包含队列头、队列尾)。

    #include <iostream> using namespace std; //循环队列(少用一个空间)长度 #define M (8+1) typedef struct node ...

  10. 【伯乐在线】FACEBOOK产品设计总监:设计APP时的14个必考题

    最近看到Facebook产品设计总监Julie Zhuo拷问产品的14个问题,非常靠谱.其中有3个问题堪称致命拷问: 1.使用前:这款产品是如何吸引到你的注意力的?2.开始使用:使用这款产品是轻松愉悦 ...