Android App Widget桌面小部件开发实践

App Widget桌面小部件已经被很多APP所使用,在日常的生活中也有很多人在使用,最常见的就是时钟、天气、日历、记事本这样的小工具,但是不少主流APP也提供了一些快捷功能的小部件,例如音乐快捷播放、代办事项、课程表、股票、购物快捷搜索、邮箱邮件等等,桌面小部件是APP部分业务功能的快捷入口,可以有效提升用户的使用体验缩短触达链路。

一、小部件基本组成

1.1 小部件UI布局

和Activity类似,在 XML 资源中为定义初始布局并将其保存在项目的 res/layout/目录中,App Widget 布局基于RemoteViews,它不支持所有类型的容器布局和视图控件。

RemoteViews 可支持的容器和控件如下:

容器

  • FrameLayout (帧布局)
  • LinearLayout (线性布局)
  • RelativeLayout (相对布局)

控件

  • AnalogClock (时钟)
  • Button (按钮)
  • Chronometer (计时器)
  • ImageButton (图片按钮)
  • ImageView (图片)
  • ProgressBar (进度条)
  • TextView (文本框)
  • ListView (纵向列表)
  • GridView (宫格)
  • StackView (堆叠)
  • ViewFlipper (翻转控件)
  • AdapterViewFlipper (翻转控件,但需要Adapter)

并且,不支持继承了上述容器和控件的View,也就是不支持自定义View。

例如:

<FrameLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@drawable/my_widget_background">

  <TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

</FrameLayout>

1.2 AppWidgetProviderInfo 元数据

AppWidgetProviderInfo 用于描述一个 App Widget 的基本属性,如布局文件、布局尺寸、布局可变方向、最小可变布局尺寸、预览图、更新频率、配置Activity。

使用单个<appwidget-provider>元素在 XML 资源文件中定义 AppWidgetProviderInfo 对象,并将其保存在项目的 res/xml 文件夹中。

例如:

<appwidget-provider 
    xmlns:android = "http://schemas.android.com/apk/res/android" 
    android:minWidth = "250dp" 
    android:minHeight = "110dp" 
    android:updatePeriodMillis = "86400000" 
    android:previewImage = "@drawable/preview" 
    android:initialLayout = "@layout/example_appwidget" 
    android:configure = "com.example.android.ExampleAppWidgetConfigure" 
    android:resizeMode = "horizo​​ntal|vertical" /> 

以下是<appwidget-provider>属性的摘要:

  • minWidthminHeight 属性的值指定默认情况下App Widget 消耗的最小空间量 。默认主屏幕根据具有定义高度和宽度的单元格网格在其窗口中定位应用小部件,如果一个App Widget的最小宽度或高度的值不匹配的单元的尺寸,则会调整到最接近的小区大小。

【注意】为适配不同的屏幕尺寸,小部件的最小尺寸不应大于 4 x 4 单元格。

  • minResizeWidthminResizeHeight属性指定 App Widget 的绝对最小尺寸。这些值应指定应用小部件即将无法辨认或无法使用的大小,使用这些属性允许用户将窗口小部件的大小调整为可能小于由minWidth和minHeight属性定义的默认窗口小部件大小的大小 。
  • updatePeriodMillis属性定义了系统更新 App Widget 的频率。不能保证使用此值准确按时进行更新,官方建议尽可能不频繁地进行更新,建议每小时不超过一次以节省电池电量,并且最小值为1800000——即30分钟。

【注意】如果设备在更新时处于睡眠状态,则设备将唤醒以执行更新。如果每小时更新不超过一次,这可能不会对电池寿命造成重大问题。但是,如果需要更频繁地更新或不需要在设备休眠时更新,那么可以根据不会唤醒设备的闹钟执行更新,使用 AppWidgetProvider 接收的 Intent 设置 AlarmManager,将闹钟类型设置为ELAPSED_REALTIME或 RTC,然后设置 updatePeriodMillis为0。

  • initialLayout属性指向定义 App Widget 布局的布局资源。
  • configure属性定义了在用户添加 App Widget 时启动的配置Activity,以便用户配置 App Widget 属性。
  • previewImage属性指定应用小部件在的外观预览图,用户在选择应用小部件时会看到该预览图。如果未提供,用户将看到APP的启动图标。
  • resizeMode属性指定可以调整小部件大小的规则。此属性使主屏幕小部件可调整大小——水平、垂直或在两个轴上。用户按住小部件以显示其调整大小手柄,然后拖动水平和/或垂直手柄以更改布局网格上的大小。该resizeMode属性的值 包括“horizo​​ntal”、“vertical”和“none”。要将小部件声明为水平和垂直均可调整大小,则使用“horizo​​ntal|vertical”。

1.3 AppWidgetProvider 类实现

AppWidgetProvider类是小部件的核心类,继承了BroadcastReceiver,可以处理广播消息。

AppWidgetProvider 仅接收与 App Widget 相关的事件广播,例如 App Widget 何时更新、删除、启用和禁用。

当这些广播事件发生时,AppWidgetProvider 的主要生命周期方法会被调用:

  • onUpdate()
    此方法会根据配置的 updatePeriodMillis 属性定义的时间间隔进行调用,作用为更新小部件,当用户添加小部件时也会调用此方法,因此它应该执行一些基本的设置。但是,如果你已经声明了一个ConfigureActivity,这个方法在用户添加小部件时不会调用,而是在后续更新时调用。ConfigureActivity负责在配置完成后执行第一次更新。
  • onDeleted(Context, int[])
    每次从桌面删除小部件时都会调用此方法。
  • onEnabled(Context)
    只有在桌面上添加对应小部件的第一个实例时会调用此方法。例如,如果用户连续添加了一个小部件两次,只有第一次添加时会调用此方法。
  • onDisabled(Context)
    当对应小部件的最后一个实例从 App Widget 主机中删除时,会调用此方法,在此方法中应执行资源释放等工作。
  • onReceive(Context, Intent)
    每次接收到广播和上述每个回调方法之前会调用此方法,主要用于处理点击事件、手动更新等事项。

例如:

public class ExampleAppWidgetProvider extends AppWidgetProvider {
   

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
   
        final int N = appWidgetIds.length;
        for (int i=0; i<N; i++) {
   
            int appWidgetId = appWidgetIds[i];

            // 创建一个打开Activity的Intent
            Intent intent = new Intent(context, ExampleActivity
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
创建 Android 应用程序中的 App Widget,需要以下步骤: 1. 创建 App Widget Provider 类 ```java public class MyWidgetProvider extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // 更新 App Widget RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout); views.setTextViewText(R.id.tv_widget, "Hello World!"); appWidgetManager.updateAppWidget(appWidgetIds, views); } } ``` 2. 声明 App Widget Provider 在 AndroidManifest.xml 文件中声明 App Widget Provider,如下所示: ```xml <receiver android:name=".MyWidgetProvider" android:label="@string/app_name"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/my_widget_info" /> </receiver> ``` 其中,MyWidgetProvider 是你的 App Widget Provider 类名,@string/app_name 是你应用的名称,@xml/my_widget_info 是你的 App Widget Provider 的相关信息,需要在 res/xml 目录下创建一个名为 my_widget_info.xml 的文件,并在该文件中指定你的 App Widget 的布局和其他属性。 3. 定义 App Widget 的布局 在 res/layout 目录下创建一个名为 widget_layout.xml 的文件,定义 App Widget 的布局,如下所示: ```xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/widget_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <TextView android:id="@+id/tv_widget" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" android:textColor="#000000" /> </RelativeLayout> ``` 4. 更新 App Widget 在 onUpdate() 方法中,更新 App Widget 的 UI。可以使用 RemoteViews 对象更新 App Widget 的 UI,如下所示: ```java @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // 更新 App Widget RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout); views.setTextViewText(R.id.tv_widget, "Hello World!"); appWidgetManager.updateAppWidget(appWidgetIds, views); } ``` 5. 安装 App Widget 在应用的首次安装时,需要向用户请求授权,以便创建 App Widget。可以使用以下代码向用户请求授权: ```java // 请求授权 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, new ComponentName(context, MyWidgetProvider.class)); int REQUEST_PICK_APPWIDGET = 1; ((Activity) context).startActivityForResult(intent, REQUEST_PICK_APPWIDGET); ``` 6. 添加 App Widget桌面 可以使用以下代码将 App Widget 添加到桌面: ```java // 添加 App Widget Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); context.sendBroadcast(intent); ``` 其中,appWidgetIds 是 App Widget 的 ID 数组,可以在 onUpdate() 方法中获取。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值