• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Android:AppWidgetProvider使用

武飞扬头像
Jason_Lee155
帮助1

学新通

AppWidget 即桌面小部件,也叫桌面控件,就是能直接显示在Android系统桌面上的小程序。图中用黄色箭头指示的即为AppWidget,一些用户使用比较频繁的程序,可以做成AppWidget,这样能方便地使用。典型的程序有时钟、天气、音乐播放器等。AppWidget 是Android 系统应用开发层面的一部分,有着特殊用途,使用得当的话,的确会为app 增色不少,它的工作原理是把一个进程的控件嵌入到别外一个进程的窗口里。需要说明的是,AppWidgetProvider本质是一个广播,即BroadcastReceiver,在实际的使用中,把AppWidgetProvider当成一个BroadcastReceiver即可。这里就简单的介绍一下开发一个AppWidget的流程吧。

想要在应用中创建一个AppWidget,至少需要以下几样东西:

  • 需要创建一个AppWidgetProviderInfo,来描述AppWidget的元数据。
  • 需要实现一个自己的AppWidgetProvider对AppWidget进行更新等操作。
  • 需要布局文件来描述AppWidget的布局。

1. 为AppWidget提供一个文件,定义小控件的基本配置信息

在资源文件夹res目录下新建xml文件夹,假设名字为flash_light_widget_info.xml,文件内容为:

  1.  
    <?xml version="1.0" encoding="utf-8"?
  2.  
    <!--小控件宽高--
  3.  
    <!--android:minWidth="40dp"--
  4.  
    <!--android:minHeight="40dp"--
  5.  
    <!--更新时间--
  6.  
    <!--android:updatePeriodMillis="86400000"--
  7.  
    <!--用于指定预览图片。即搜索到widget时,查看到的图片。若没有设置的话,系统为指定一张默认图片。--
  8.  
    <!--android:previewImage="@drawable/widget_flashlight"--
  9.  
    <!--widget 添加到手机主屏幕中的layout--
  10.  
    <!--android:initialLayout="@layout/flash_light_widget"--
  11.  
    <!--android:resizeMode : widget可以被拉伸的方向。horizontal表示可以水平拉伸,vertical表示可以竖直拉伸--
  12.  
    <!--android:resizeMode="horizontal|vertical"--
  13.  
     
  14.  
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
  15.  
    android:minWidth="40dp"
  16.  
    android:minHeight="40dp"
  17.  
    android:updatePeriodMillis="86400000"
  18.  
    android:previewImage="@drawable/ic_launcher"
  19.  
    android:initialLayout="@layout/widget_layout"
  20.  
    android:resizeMode="horizontal|vertical"
  21.  
    </appwidget-provider
学新通

2. 创建一个WidgetProvider继承自AppWidgetProvider;

  1.  
    public class MyAppWidgetProvider extends AppWidgetProvider {
  2.  
    //没接收一次广播消息就调用一次,使用频繁
  3.  
    public void onReceive(Context context, Intent intent) {
  4.  
    super.onReceive(context, intent);
  5.  
    }
  6.  
     
  7.  
    //每次更新都调用一次该方法,使用频繁
  8.  
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
  9.  
    int[] appWidgetIds) {
  10.  
    super.onUpdate(context, appWidgetManager, appWidgetIds);
  11.  
    }
  12.  
     
  13.  
    //没删除一个就调用一次
  14.  
    public void onDeleted(Context context, int[] appWidgetIds) {
  15.  
    super.onDeleted(context, appWidgetIds);
  16.  
    }
  17.  
     
  18.  
    //当该Widget第一次添加到桌面是调用该方法,可添加多次但只第一次调用
  19.  
    public void onEnabled(Context context) {
  20.  
    super.onEnabled(context);
  21.  
    }
  22.  
     
  23.  
    //当最后一个该Widget删除是调用该方法,注意是最后一个
  24.  
    public void onDisabled(Context context) {
  25.  
    super.onDisabled(context);
  26.  
    }
  27.  
    }
学新通

3. 为 WidgetProvider创建一个布局文件

布局就是正常布局,假设名字为widget_layout.xml:

  1.  
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.  
    android:layout_width="64dp"
  3.  
    android:layout_height="64dp"
  4.  
     
  5.  
    <ImageButton
  6.  
    android:id="@ id/widget_led"
  7.  
    android:layout_margin="2dp"
  8.  
    android:background="@drawable/widget_led"
  9.  
    android:src="@drawable/ic_launcher"
  10.  
    android:scaleType="center"
  11.  
    android:layout_width="64.0dip"
  12.  
    android:layout_height="64.0dip" /
  13.  
     
  14.  
    </RelativeLayout

4. 注册Manifest.xml

配置基本和广播一样,使用receiver 节点,meta-data 节点的name 为固定格式,resource为第一步定义的配置信息,intent-filter节点第三个action必须提供:

  1.  
    <receiver android:name=".jf.jfclean.widget.FlashLightWidget"
  2.  
    <intent-filter
  3.  
    <action android:name="action_led_on" /
  4.  
    <action android:name="action_led_off" /
  5.  
    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /
  6.  
    </intent-filter
  7.  
     
  8.  
    <meta-data
  9.  
    android:name="android.appwidget.provider"
  10.  
    android:resource="@xml/flash_light_widget_info" /
  11.  
    </receiver

5. 使用PendingIntent和RemoteViews对AppWidget进行更新

  1.  
    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
  2.  
    int appWidgetId) {
  3.  
     
  4.  
    CharSequence widgetText = context.getString(R.string.appwidget_text);  
  5.  
    // Construct the RemoteViews object
  6.  
    RemoteViews views = new RemoteViews(context.getPackageName(),
  7.  
    // 这个layout就是我们之前定义的initiallayout
  8.  
    R.layout.my_app_widget_provider);
  9.  
    // 更新里面某一个子view值
  10.  
    views.setTextViewText(R.id.appwidget_text, widgetText);
  11.  
    // Instruct the widget manager to update the widget
  12.  
    appWidgetManager.updateAppWidget(appWidgetId, views);
  13.  
    }
  14.  
     
  15.  
    @Override
  16.  
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
  17.  
    // There may be multiple widgets active, so update all of them
  18.  
    for (int appWidgetId : appWidgetIds) {
  19.  
    updateAppWidget(context, appWidgetManager, appWidgetId);
  20.  
    }
  21.  
    // 或者点击widget跳转逻辑
  22.  
    mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.mul_app_widget_provider);
  23.  
    mRemoteViews.setImageViewResource(R.id.iv_test, R.mipmap.ic_launcher);
  24.  
    mRemoteViews.setTextViewText(R.id.btn_test, "点击跳转到Activity");
  25.  
    Intent skipIntent = new Intent(context, MainActivity.class);
  26.  
    PendingIntent pi = PendingIntent.getActivity(context, 200, skipIntent, PendingIntent.FLAG_CANCEL_CURRENT);
  27.  
    mRemoteViews.setOnClickPendingIntent(R.id.btn_test, pi);
  28.  
    }
学新通

这里,简单介绍下RemoteViews:

RemoteViews

RemoteViews,从字面意思理解为它是一个远程视图。是一种远程的 View,它在其它进程中显示,却可以在另一个进程中更新。RemoteViews 在Android中的使用场景主要有:自定义通知栏和桌面小部件。

在RemoteViews 的构造函数中,第二个参数接收一个 layout 文件来确定 RemoteViews 的视图;然后,我们调用RemoteViews 中的 set 方法对 layout 中的各个组件进行设置,例如,可以调用 setTextViewText() 来设置 TextView 组件的文本。

widget小部件布局文件可以添加的组件是有限制的,它可以支持的 View 类型包括四种布局:FrameLayout、LinearLayout、RelativeLayout、GridLayout 和 13 种View: AnalogClock、Button、Chronometer、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView、AdapterViewFlipper、ViewSub。注意:RemoteViews 也并不支持上述 View 的子类。

RemoteViews 提供了一系列 setXXX() 方法来为小部件的子视图设置属性。具体可以参考 API 文档。

RemoteViewsService

RemoteViewsService,是管理RemoteViews的服务。一般,当AppWidget 中包含 GridView、ListView、StackView 等集合视图时,才需要使用RemoteViewsService来进行更新、管理。RemoteViewsService 更新集合视图的一般步骤是:

  1. 通过 setRemoteAdapter() 方法来设置 RemoteViews 对应 RemoteViewsService 。
  2. 之后在 RemoteViewsService 中,实现 RemoteViewsFactory 接口。然后,在 RemoteViewsFactory 接口中对集合视图的各个子项进行设置,例如 ListView 中的每一Item。

RemoteViewsFactory

通过RemoteViewsService中的介绍,我们知道RemoteViewsService是通过 RemoteViewsFactory来具体管理layout中集合视图的,RemoteViewsFactory是RemoteViewsService中的一个内部接口。RemoteViewsFactory提供了一系列的方法管理集合视图中的每一项。例如:

  • RemoteViews getViewAt(int position)

通过getViewAt()来获取“集合视图”中的第position项的视图,视图是以RemoteViews的对象返回的。

  • int getCount()

通过getCount()来获取“集合视图”中所有子项的总数。


简单回顾发现,AppWidget常见就是放在Launcher上的一块控件,实际上是有其他进程(比如音乐)提供数据的,xml定义的循环时间通过AppManager更新。点击widget点击事件也是在AppWidgetProvider里提供。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhficbbg
系列文章
更多 icon
同类精品
更多 icon
继续加载