根据应用的需要,有的APP中内嵌了桌面小部件代码,以至于我们可以通过长按手机屏幕-->小部件-->选择你需要添加的应用小部件。这样可以给用户提过了较好的、快捷的使用体验方式,这边是Android桌面小部件的实际意义。
下图是有道词典的一个桌面小部件的实例(另外红日的icon便是红日APP的一个简单的桌面小部件):
AppWidgetProvider是Android提供的用于实现桌面小部件的类,其本质是一个广播。另外也用到了RemoteViews这个类,这是一个跨进程的远程类,使用场景有两种:通知栏和小部件。
小部件的开发步骤:
1、定义小部件界面
res/layout目录下新建一个xml布局文件,这里是widget.xml,布局很简单只是一张红日的icon
<?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">
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/sun" />
</LinearLayout>
2、定义小部件配置信息:
res/xml目录下新建一个xml布局文件,这里是new_app_widget_info.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/widget"
android:initialLayout="@layout/widget"
android:minHeight="40dp"
android:minWidth="40dp"
android:previewImage="@drawable/example_appwidget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen">
</appwidget-provider>
其中initialLayout引用到了前面定义的小部件的布局文件widget.
3、定义小部件的实现类:
package xml;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.SystemClock;
import android.widget.RemoteViews;
import com.hongri.recyclerview.R;
import com.hongri.recyclerview.utils.Logger;
/**
* 桌面小部件实现类.
*/
public class NewAppWidget extends AppWidgetProvider {
private static final String CLICK_ACTION = "android.appwidget.action.click";
private static RemoteViews remoteViews;
public NewAppWidget(){
super();
}
/**
* 桌面小部件更新
* @param context
* @param appWidgetManager
* @param appWidgetId
*/
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
Logger.d("updateAppWidget");
sendPendingIntentCast(context);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
@Override
public void onReceive(final Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(CLICK_ACTION)){
Logger.d("onReceive--CLICK_ACTION");
new Thread(new Runnable() {
@Override
public void run() {
Bitmap srcbBitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.sun);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
for (int i = 0; i < 37; i++) {
float degree = (i*10) % 360;
sendPendingIntentCast(context);
remoteViews.setImageViewBitmap(R.id.imageView1,rotateBitmap(context,srcbBitmap,degree));
appWidgetManager.updateAppWidget(new ComponentName(context,NewAppWidget.class),remoteViews);
SystemClock.sleep(30);
}
}
}).start();
};
}
/** 设置旋转动画 */
private Bitmap rotateBitmap(Context context, Bitmap srcbBitmap, float degree) {
Matrix matrix = new Matrix();
matrix.reset();
matrix.setRotate(degree);
Bitmap tmpBitmap = Bitmap.createBitmap(srcbBitmap,0,0,srcbBitmap.getWidth(),srcbBitmap.getHeight(),matrix,true);
return tmpBitmap;
}
/**
* "桌面小部件"点击发送的Intent广播
* @param context
*/
private static void sendPendingIntentCast(Context context) {
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
Intent intentClick = new Intent();
intentClick.setAction(CLICK_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,intentClick,0);
remoteViews.setOnClickPendingIntent(R.id.imageView1,pendingIntent);
}
/**
* 每次桌面小部件更新时都会调用该方法
* @param context
* @param appWidgetManager
* @param appWidgetIds
*/
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Logger.d("onUpdate");
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
}
4、AndroidManifest.xml文件中声明小部件(小部件的机制就是广播,所以必须声明):
<receiver android:name="xml.NewAppWidget">
<intent-filter>
<action android:name="android.appwidget.action.click"></action>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/new_app_widget_info" />
</receiver>
最后运行程序没问题时,可以将小部件添加到桌面:
长按桌面-->进入小部件-->红日app-->店家该app下的此小部件