Android开发基本控件AppWidget的基本使用

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: ");
    }
}

Leave a Reply