Android中AppWidget的学习整理(附demo)
来源:互联网 发布:网络理财客服招聘 编辑:程序博客网 时间:2024/05/02 01:54
今天写的是AppWidget,这是我工作之后接触的第一个模块。乘着有时间整理下知识点。
先附上DEMO:http://download.csdn.net/detail/violetjack0808/9433218
这里实现的是一个用来计数的AppWidget桌面小部件。效果图如下:
下面是实现步骤
1.创建AppWidget配置文件
在res/xml目录下创建app_widget_config.xml文件,用来配置widget属性。
<?xml version="1.0" encoding="utf-8"?><appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/widget_ui" android:minHeight="140dip" android:minWidth="140dip" android:updatePeriodMillis="6890000" ></appwidget-provider>
这个xml是用来描述所要创建的appWidget的一些描述信息的,所描述的属性分别有最小高度、最小宽度、刷新间隔和关联布局文件布局文件。
特别要说的是AppWidget的大小是以格为单位来计算的,手机屏幕被分为一个4*4的格阵,当宽高到达一定值时就会显示并占满相应的格数,不会出现自定义不规则的大小的。网上资料显示说N格的长宽为(74*N)-2。我设定的140*140显示的是2*2的界面。
在res/layout中创建widget_ui.xml这个布局文件。这里画的布局就会是我们在手机桌面上看到的widget的样子啦~
<?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:orientation="vertical"> <TextView android:id="@+id/tvTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="this is a widget" /> <TextView android:id="@+id/tvResult" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="result = 0"/> <Button android:id="@+id/btnAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="add one"/></LinearLayout>
3.创建AppWidgetProvider
在src目录下创建AppWidget类继承自AppWidgetProvider,用以实现widget的交互。
当我看到onReceive方法觉得奇怪,这不是广播接收器吗?结果进去一看发现AppWidgetProvider就是继承自BroadcastReceiver的
public class AppWidgetProvider extends BroadcastReceiver
所以,widget的工作原理就是通过广播来实现对它的控制的。
3.1 AppWidgetProvider的生命周期:
onEnabled当AppWidget实例第一次被创建时调用。
onReceive接收广播事件。
onUpdate到达指定的更新时间或用户向桌面添加widget时候调用。
onDeleted当AppWidget被删除时调用。
onDisabled当最后一个AppWidget被删除时调用。
3.2.RemoteViews和PendingIntent
在onUpDate方法中用到了RemoteViews与PendingIntent, 是因为AppWidget和其原本的App并不在同一个进程中,而是运行在HomeScreen进程当中,因此,在控件监听器的绑定,更新等操作都会与以前基本的方法有所不同。
PendingIntent是一个特殊的Intent,实际上它像一个邮包,其中包裹着真正的Intent,当邮包未打开时,Intent是被“挂起”的,所以并不执行,只有当邮包拆开时才会执行。它与Intent的区别在于:Intent 是及时启动,intent 随所在的activity 消失而消失。 进程A创建PendingIntent,发送给进程B,进程B此事并不执行,直到用户出发某一事件时,包裹被拆开,里面的Intent真正执行。所以Intent什么时候被执行是不知道的,由用户出发事件来决定。
RemoteViews表示了一系列view对象,即AppWidget所有的控件。它的应用方法如下源码所示,使用了views.setOnClickPendingIntent(所需控件的ID,定义的pendingintent)方法来为控件绑定监听器。
3.3 源码
/** * AppWidget学习demo * 个人心得: * onUpDate方法用于创建和更新AppWidget,将所需的ID通过intent进行传递。 * onReceive方法通过接收intent传送的广播事件实现AppWidget的变化操作。 */public class AppWidget extends AppWidgetProvider { private static int i = 1; private static final String ACTION = "click"; //当AppWidget实例第一次被创建时调用。 @Override public void onEnabled(Context context) { super.onEnabled(context); } //接收广播事件。 @Override public void onReceive(Context context, Intent intent) { Log.e("widget", "onReceive + " + intent.getAction()); super.onReceive(context, intent); ComponentName thisWidget = new ComponentName(context,AppWidget.class);//定义容器 RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_ui);//定义RemoteViews //定义AppWidgetManager,用于之后更新AppWidget AppWidgetManager appWidgetManager = AppWidgetManager .getInstance(context); //通过接收广播的Intent来进行widget的UI操作 if (intent.getAction().equals(ACTION)) { views.setTextViewText(R.id.tvResult, "result = " + i); i++; } //更新AppWidget appWidgetManager.updateAppWidget(thisWidget, views); } //到达指定的更新时间或用户向桌面添加widget时候调用。 public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) { Log.e("widget", "onUpdate"); for (int id : appWidgetIds) { RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_ui); Intent intent1 = new Intent("click");//定义intent PendingIntent pendingIntentOne = PendingIntent.getBroadcast(context, 0, intent1, 0);//用PendingIntent将Intent包裹起来 views.setOnClickPendingIntent(R.id.btnAdd, pendingIntentOne);//按钮点击事件监听 //更新AppWidget appWidgetManager.updateAppWidget(id, views); } } //当AppWidget被删除时调用。 @Override public void onDeleted(Context context, int[] appWidgetIds) { super.onDeleted(context, appWidgetIds); } //当最后一个AppWidget被删除时调用。 @Override public void onDisabled(Context context) { super.onDisabled(context); }}
4.注册广播
上面提到了,AppWidgetProvider其实就是广播,所以我们需要在Manifest文件中注册广播。
这里注意Action的一致。关于广播的知识可以看我的Blog:Android广播Broadcast的学习(附demo)
代码:
<application .... > ..... <receiver android:name=".AppWidget" > <meta-data android:name="android.appwidget.provider" android:resource="@xml/app_widget_config" /> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="click" /> </intent-filter> </receiver> ....</application>注意:resource要关联我们之前写的app_widget_provider.xml文件;action中第一个必须写,第二个就是自定义action了。
这样一个计数的桌面小部件就完成啦~
- Android中AppWidget的学习整理(附demo)
- Android广播Broadcast的学习(附demo)
- Android MVP架构学习(附demo)
- Android学习--AppWidget的使用
- android中Appwidget的使用
- 如何在自己的程序中添加appWidget(附简单代码)
- RxJava的学习(附demo)
- android:AppWidget 窗口小部件的开发思想和Demo
- android 中 AppWidget 的 ListView 的实现
- Android中AppWidget的创建和使用
- Android中自定义可以下拉刷新的ListView(附demo)
- Android中AppWidget加载流程(一)
- Android中AppWidget加载流程(二)
- Android中AppWidget加载流程(一)
- Android中AppWidget加载流程(二)
- Android中AppWidget详解
- Android AppWidget详解,内附详细注释
- Android下对Cookie的读写操作(附Demo)
- [干货]系统吞吐量(TPS)、用户并发量、性能测试概念和公式
- Android 中的沉浸式状态栏
- JVM工作原理、机制
- 关于WEB-INF下的jsp,使用绝对路径如何访问?
- 【持久化框架】Mybatis简介与原理
- Android中AppWidget的学习整理(附demo)
- docker attch退出
- springmvc中@PathVariable和@RequestParam的区别
- 使用python爬取csdn博客访问量
- nyoj--1100--WAJUEJI which home strong!(bfs)
- CMake使用教程
- Hive 1.2.1&Spark&Sqoop安装指南
- spring 4.0.6 + mybatis 3.2.5 + mybatis-spring 1.2.3 构造多个数据源的配置
- 快速使用github