当前位置: 代码迷 >> Android >> 【安卓札记】Widget
  详细解决方案

【安卓札记】Widget

热度:332   发布时间:2016-04-28 03:05:11.0
【安卓笔记】Widget
什么是Widget?
App Widget是android提供的桌面小工具,它能够嵌入到桌面,并且可以定期更新自己的数据。
如下图所示:

如何创建Widget?
创建一个Widget需要以下几个组件:
1AppWidgetProviderInfo:这个类提供了Widget的元数据,比如Widget的布局,更新频率,大小等等。它通常都使用xml定义,位置为res/xml。
2.AppWidgetProvider:这个类是一个广播接收者,用来接收一些广播信息,比如widget是否可用、widget更新、widget被删除等。通常,我们需要继承这个类并复写onXXX等生命周期方法。
3.Widget布局:创建Widget需要指定其布局,这个在res/layout下定义即可。
4.AppWidgetManager:这个类可以更新Widget的状态,并可以获取已经注册的AppWidgetProvider的信息。

创建Widget的步骤:
1.定义一个类继承AppWidgetProvider:
package com.example.widget;import android.appwidget.AppWidgetManager;import android.appwidget.AppWidgetProvider;import android.content.Context;public class MyWidgetProvider extends AppWidgetProvider{	@Override	public void onEnabled(Context context)	{		super.onEnabled(context);	}	@Override	public void onUpdate(Context context, AppWidgetManager appWidgetManager,			int[] appWidgetIds)	{		super.onUpdate(context, appWidgetManager, appWidgetIds);	}	@Override	public void onDisabled(Context context)	{		super.onDisabled(context);	}}
2.在res/layout下定义widget的布局:
比如叫widget_layout.xml
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:padding="2dp"     >    <LinearLayout         android:layout_width="match_parent"        android:layout_height="match_parent"		android:orientation="horizontal"                >        <Button             android:id="@+id/btn"              android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="打开软件"            android:textColor="@android:color/black"            />        <TextView             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="这是一个widget"            />    </LinearLayout></FrameLayout>
3.在res/xml目录下创建一个xml资源,定义widget的基本信息:
比如叫:app_widget_info.xml
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"    android:initialLayout="@layout/widget_layout"    android:minHeight="50dp"    android:minWidth="290dp"    android:updatePeriodMillis="86400000" ></appwidget-provider>
还有一些其他标签,用法参见文档。

4.在清单文件中配置AppWidgetProvider:
<receiver android:name="com.example.widget.MyWidgetProvider" >            <intent-filter><!--action name是固定的-->                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />            </intent-filter>            <meta-data                android:name="android.appwidget.provider"                android:resource="@xml/app_widget_info" /></receiver>
至此,Widget创建完成,效果如下:

这时候的button是没有点击效果的,那么如何为其增加按钮点击的响应事件呢?
那就要使用到AppWidgetManager了。
在这之前我们先介绍下Widget的生命周期,可以在上面MyWidgetProvider中打log,通过分析log我们可以得出如下结论:
1.第一个widget被拖到桌面上:onEnabled()--->onUpdate()
2.以后每个widget被拖到桌面上:onUpdate()
3.删除一个Widget:onDeleted()
4.最后一个widget被删除:onDeleted()-->onEnabled()
另外,如果你复写了onReceive方法,那么onReceive方法是最先执行的(确保要调用super.onReceive)。其实我们分析下AppWidgetProvider源码就很容易看出来,AppWidgetProvider在onReceive方法中通过判断action类型,来执行不同的业务方法,而具体的业务方法是由子类来复写的。

5.添加响应事件
既然每个widget被拖到桌面都会调用onUpdate,那么我们就在这个方法中为按钮添加监听:
@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds)	{		Log.d(TAG,"onUpdate...");		RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.widget_layout);		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(context,MainActivity.class),0);		views.setOnClickPendingIntent(R.id.btn, pendingIntent);		appWidgetManager.updateAppWidget(appWidgetIds, views);	}
这里需要用到AppWidgetManager的updateAppWidget方法,这个方法需要传入widget的id和RemoteViews。这个RemoteViews很关键,我们要为按钮添加响应事件,就得调用这个类的setOnClickPendingIntent方法,当然了,它也提供了很多其他方法,诸如setTextViewText、setProgressBar等,这些方法有个共同点,那就是必须传入view的id。更多用法请查看文档。
通过上面的方法,当我们点击按钮时,就可以打开主界面了!

widget通常需要配合service使用。因为,widget需要定时更新信息,所以一个后台服务必不可少。这时候我们可以再onEnabled中启动服务,然后在服务中增加一个定时器(Timer或者AlarmManager),定期更新widget,这时候可以通过
AppWidgetManager.getInstance(context);
获取AppWidgetManager实例。


以上是widget的基本用法,更多用法参见文档。











  相关解决方案