1、先上图,再说话
2、设计与实现
2.1、App Widget即我们常说的桌面插件或叫“小工具”;
2.2、上图中即为我们需要实现的小工具,面板中一个按钮一个文本框;
2.3、需要实现的功能是点击按钮能将文本框中的文字改成后者;
2.4、App Widget核心类是AppWidgetProvider,与之关联的还有两个XML;
2.5、一个XML为App Widget提供基本属性(数据层面的属性new_app_widget_info.xml);
2.6、另一个XML为App Widget提供布局描述new_app_widget.xml;
2.7、除此之外还要在AndroidManifest.xml中注册,注册一个reciver;
2.8、值得一提的是App Widget的核心类继承自BroadcastReceiver,即App Widget实现是基于广播的;
2.9、Andoid Studio直接新建一个App Widget类会帮我们自动将上述多个文件都自动创建好;
3、关键代码
AndroidManifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yusian.widget"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".NewAppWidget"> <!--注册widget,widget本身实现也是基于广播--> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <!--注册广播--> <intent-filter> <action android:name="com.yusian.widget.broadcast"/> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/new_app_widget_info" /> </receiver> </application> </manifest> |
new_app_widget_info.xml
1 2 3 4 5 6 7 8 9 10 11 12 | <?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialKeyguardLayout="@layout/new_app_widget" android:initialLayout="@layout/new_app_widget" android:minHeight="40dp" android:minWidth="360dp" android:previewImage="@drawable/example_appwidget_preview" android:resizeMode="horizontal|vertical" android:updatePeriodMillis="86400000" android:widgetCategory="home_screen"> </appwidget-provider> |
new_app_widget.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#09C" android:orientation="vertical"> <TextView android:id="@+id/appwidget_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_margin="8dp" android:background="#09C" android:contentDescription="@string/appwidget_text" android:text="@string/appwidget_text" android:textColor="#ffffff" android:textSize="24sp" android:textStyle="bold|italic" /> <Button android:id="@+id/btn_widget" android:layout_width="match_parent" android:layout_height="60dp" android:text="按钮"/> </LinearLayout> |
NewAppWidget
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | package com.yusian.widget; 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.util.Log; import android.widget.RemoteViews; /** * Implementation of App Widget functionality. */ public class NewAppWidget extends AppWidgetProvider { private final static String UPDATE_ACTION = "com.yusian.widget.broadcast"; @Override public void onReceive(Context context, Intent intent) { Log.d("SALog", "onReceive: " + intent.getAction()); // 响应UPDATE_ACTION广播事件 if (intent.getAction().equals(UPDATE_ACTION)) { // 1、内容变更 RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.new_app_widget); remoteViews.setTextViewText(R.id.appwidget_text, "AppWidgetText"); // 2、更新视图 AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); ComponentName componentName = new ComponentName(context, this.getClass()); appWidgetManager.updateAppWidget(componentName, remoteViews); }else{ super.onReceive(context, intent); } } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // There may be multiple widgets active, so update all of them for (int i = 0; i < appWidgetIds.length; i++) { updateAppWidget(context, appWidgetManager, appWidgetIds[i]); // 1、点击按键事件打开当前控制器 // Intent intent = new Intent(context, MainActivity.class); // PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); // 2、点击按钮事件发送一个广播 Intent intent = new Intent(); intent.setAction(UPDATE_ACTION); // 将Intent包含到一个PendingIntent内 PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); // 找到相对应的widget绑定PendingIntent RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.new_app_widget); remoteViews.setOnClickPendingIntent(R.id.btn_widget, pendingIntent); // 将widgetManager更新相关事件 appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews); } super.onUpdate(context, appWidgetManager, appWidgetIds); Log.d("SALog", "onUpdate: "); } static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { CharSequence widgetText = context.getString(R.string.appwidget_text); // Construct the RemoteViews object RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget); views.setTextViewText(R.id.appwidget_text, widgetText); // Instruct the widget manager to update the widget appWidgetManager.updateAppWidget(appWidgetId, views); } @Override public void onEnabled(Context context) { // Enter relevant functionality for when the first widget is created Log.d("SALog", "onEnabled: "); } @Override public void onDeleted(Context context, int[] appWidgetIds) { super.onDeleted(context, appWidgetIds); Log.d("SALog", "onDeleted: "); } @Override public void onDisabled(Context context) { // Enter relevant functionality for when the last widget is disabled Log.d("SALog", "onDisabled: "); } } |