0%

简单的桌面小部件

实现一个简单的桌面小部件,响应点击事件,更新等功能。

  1. 定义小部件界面
  2. 定义小部件配置信息
  3. 定义小部件的实现类
  4. 声明小部件
    在AndroidStudio中只需要在main\java下新建一个widget,就可以了,IDE会自动在res\layout添加布局文件,在res\xml下新建配置信息文件。然后就可以进行具体实现了。

AS下新建widget

定义小部件界面

RemoteView目前并不能支持所有的View,现在支持的类型如下:

  • Layout
    • FrameLayout
    • LinearLayout
    • RelativeLayout
    • GridLayout
  • View
    • AnalogClock
    • Button
    • Chronometer
    • ImageButton
    • ImageView
    • ProgressBar
    • TextView
    • ViewFlipper
    • ListView
    • GridView
    • StackView
    • AdapterViewFlipper
    • ViewStub

这个没什么好说的,按照写界面布局的方式写就好了,但是不建议写过于复杂的布局。

定义小部件配置信息

下面的代码就是IDE自动成的配置信息文件,不喜欢IDE代劳的同学可以自己创建。

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/test_remote_view_widget"
android:initialLayout="@layout/test_remote_view_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:布局文件
previewImage: 预览的图片
updatePeriodMillis:刷新周期,单位毫秒

定义小部件的实现类

实现的功能是当点击这个小部件的时候改变文字内容

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
public class TestRemoteViewWidget extends AppWidgetProvider {

private static final String CLICK_ACTION = "com.huangyuan.testwidget.TAP_CLICK_ACTION";
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Toast.makeText(context,"onReceive:" + intent.getAction(),Toast.LENGTH_SHORT).show();
if(intent.getAction().equals(CLICK_ACTION)){
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.test_remote_view_widget);
remoteViews.setTextViewText(R.id.appwidget_text,"点击");
appWidgetManager.updateAppWidget(new ComponentName(context,TestRemoteViewWidget.class),remoteViews);
}
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Toast.makeText(context,"onUpdate" ,Toast.LENGTH_SHORT).show();
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.test_remote_view_widget);
Intent clickIntent = new Intent();
clickIntent.setAction(CLICK_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,clickIntent,0);
remoteViews.setOnClickPendingIntent(R.id.appwidget_text,pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds,remoteViews);
}
}

其中还有其他方法:

  • onEnabled:当该窗口小部件第一次添加到桌面时调用该方法,可添加多次,但只在第一次调用
  • onUpdate:小部件被添加时或者每次小部件更新时都会调用一次该方法,小部件的更新时机由updatePeriodMillis指定。
  • onDeleted:每删除一次桌面小部件就调用一次。
  • onDisabled:当最后一个该类型的桌面小部件被删除时调用该方法,追时最后一个。
    需要注意的是,更新remoteView时,不能直接访问里面的View,需要通过RemoteView所提供的一系列方法更新View。
  • 更新文本: remoteViews.setTextViewText();
  • 更新图片: remoteViews.setImageViewResource();remoteViews.setImageViewBitmap();
  • 添加单击事件:remoteViews.setOnClickPendingIntent();