相信大家对桌面小组件一定不陌生吧,也一定向想开发一个属于自己的桌面小组件,那么,这篇文章就带领大家一起来做一个简单的小组件。
首先,先介绍一下桌面小组件的实现过程及原理。
1.首先,要实现一个桌面小组件,必须要继承自AppWidgetProvider,其本质上是一个BroadcastReceiver,所以在使用AppWidgetProvider时需要在xml中注册这一小组件。
2.重写onReceive和onUpdate方法,当广播来时,AppWidgetProvider会自动根据广播的action通过onReceive方法分发广播,即,广播来时,会先进入onReceive方法,而在onReceive方法中,AppWidgetProvider会根据所收到的action选择调用onUpdate,onEnable等方法。
3.AppWidgetProvider的布局是由remoteViews来展示的,通过创建一个remoteViews并设置其参数即可实现自定义布局的显示。具体下面会给出示例代码。
4.AppWidgetProvider是通过AppWidgetManger来控制的。
下面给出具体代码实现:
package ctc.com.koltintext; 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; /** * Created by ctc on 2016/7/22. */ public class ClientWidget extends AppWidgetProvider { private static final String CLICK_ACTION = "ctc.com.koltinText.action.click"; public ClientWidget(){ super(); } @Override public void onReceive(final Context context, final Intent intent) { super.onReceive(context, intent); if (intent.getAction().equals(CLICK_ACTION)){ new Thread(new Runnable() { @Override public void run() { Bitmap recBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_orange); AppWidgetManager manager = AppWidgetManager.getInstance(context); for (int i = 0; i < 37; i++){ float dgree = (i * 10) % 360; RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); remoteViews.setImageViewBitmap(R.id.WidgetImage, rotateImage(recBitmap, dgree)); Intent intentClick = new Intent(); intentClick.setAction(CLICK_ACTION); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0); remoteViews.setOnClickPendingIntent(R.id.WidgetImage, pendingIntent); manager.updateAppWidget(new ComponentName(context, ClientWidget.class), remoteViews); SystemClock.sleep(60); } } }).start(); } } /** * 旋转图片 * @param recBitmap 旋转图片 * @param dgree 旋转角度 * */ private Bitmap rotateImage(Bitmap recBitmap, float dgree){ Matrix matrix = new Matrix(); matrix.reset(); matrix.setRotate(dgree); retrun Bitmap.createBitmap(recBitmap, 0, 0, recBitmap.getWidth(), recBitmap.getHeight(), matrix, true); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); final int counter = appWidgetIds.length; for (int i = 0; i < counter; i++){ int appWidgetId = appWidgetIds[i]; onAppWidgetUpdate(context, appWidgetManager, appWidgetId); } } private void onAppWidgetUpdate(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); Intent intentClick = new Intent(); intentClick.setAction(CLICK_ACTION); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0); remoteViews.setOnClickPendingIntent(R.id.WidgetImage, pendingIntent); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } }
然后是布局文件,很简单 res/layout/widget_layout.xml
xml version="1.0" encoding="utf-8"?>xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/icon_orange" android:id="@+id/WidgetImage"/>
配置桌面小组件 res/xml/appConfig.xml
xml version="1.0" encoding="utf-8"?>xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/widget_layout" android:minHeight="84dp" android:minWidth="84dp" android:updatePeriodMillis="86400000" >
最后是注册桌面小组件
android:name=".ClientWidget">
android:name="android.appwidget.provider"
android:resource="@xml/widgetconfig">
android:name="ctc.com.koltinText.action.click"/>
android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
注意,下面这个action必须有,是桌面小部件的标志,如果不加,在小部件列表中看不到此小部件
android:name="android.appwidget.action.APPWIDGET_UPDATE"/>