Android UI组件AppWidget控件入门详解

Widget引入

我们可以把Widget理解成放置在桌面上的小组件(挂件),有了Widget,我们可以很方便地直接在桌面上进行各种操作,例如播放音乐。

当我们长按桌面时,可以看到Widget选项,如下图所示:

点击上图中箭头处的widgets图标,会出现如下界面:(都是widget)

长按上图中的任意一个widget,就可以将其放到桌面上。

Widget的使用
Widget的实现思路 
(1)在AndroidManifest中声明AppWidget; 
(2)在xml目录中定义AppWidget的配置文件; 
(3)在layout目录中定义Widget的布局文件; 
(4)新建一个类,继承AppWidgetProvider类,实现具体的widget业务逻辑。

我们需要新建一个类,继承AppWidgetProvider。点开AppWidgetProvider,发现AppWidgetProvider竟然是继承自BroadcastReceiver。

为什么Widget是一个广播接收器呢?我们知道,BroadcastReceiver类中有一个onReceive方法,用来接收广播。当我们在桌面挂件上去做操作时,必然引起应用的改变,这就涉及到挂件和应用之间的通信,此时用广播来通信是再好不过了。

Widget的具体使用步骤

(1)新建一个类TestWidget.java,继承AppWidgetProvider:
 TestWidget.java:

import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
/**
 * Created by smyhvae on 2016/9/7.
 */
public class TestWidget extends AppWidgetProvider{
 @Override
 public void onReceive(Context context, Intent intent) {
  super.onReceive(context, intent);
 }
}

(2)因为Widget是一个广播接收器,所以我们需要在清单文件中注册:

 <!-- 声明widget对应的AppWidgetProvider -->
  <receiver android:name=".TestWidget">
   <intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
   </intent-filter>
   <meta-data
    android:name="android.appwidget.provider"
    android:resource="@layout/widget_setting"/>
  </receiver>

04行:action是过滤条件,用来过滤行为,监测widget的更新。
08行:android:resource指定了widget的配置。我们知道,属性在清单文件中是用来存储数据的。

(3)layout文件夹中新建文件widget_setting.xml:(widget的配置文件)
 setting_widget.xml:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:initialLayout="@layout/layout_widget"
     android:minHeight="140dp"
     android:minWidth="140dp"
     android:previewImage="@mipmap/ic_launcher"
     android:updatePeriodMillis="20000"
     android:widgetCategory="home_screen"
 >
</appwidget-provider>

08行: android:initialLayout 指定了widget的布局。
09行:android:updatePeriodMillis 指定更新的时间周期
10行: android:widgetCategory="home_screen" 将widget显示在主屏幕上(也可以显示在锁屏上)

(4)layout文件夹中新建文件layout_widget.xml:(widget的布局)
 layout_widget.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
 <TextView
  android:id="@+id/textView"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:text="Large Text"
  android:textAppearance="?android:attr/textAppearanceLarge"/>
 <Button
  android:id="@+id/button2"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:text="New Button"/>
</LinearLayout>

到此,程序就可以跑起来了。运行程序之后,长按桌面,点开"Widget"按钮,可以看到我们刚刚设计出的widget:

长按上图中的箭头处,就可以将我们设计出的widget拖放到桌面上了:

Widget的点击和更新【重要】

我们知道,TestWidget.java继承自AppWidgetProvider,而AppWidgetProvider在继承BroadcastReceiver之后,重写onReceive方法,然后还自定义了很多方法:

上图中,包含了被删除时、被禁用时、被启用时、被更新时等各种方法。尤其重要的是onReceive()方法和onUpDate()方法。
 当小部件被改变时(比如被安装到桌面),系统会发送一个更新的广播(上图红框部分所示)。我们在setting_widget.xml中设置了widget的更新频率,这个也会调用更新。

有人可能会问,我开机之后,天气等widget为何不更新了?这是因为进程被杀死了,那我们只能把这个控件先移除,然后再装上,此时应用会发update更新的广播。

当需要做widget的点击和更新时,我们需要在需要重写onUpdate()方法,用来发送广播。当程序初始化的时候,系统就会调用onUpdate()方法。

onUpdate()方法中的代码如下:

  @Override
 public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
  super.onUpdate(context, appWidgetManager, appWidgetIds);
  RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_widget);//需要构造一个RemoteViews
  Intent intent = new Intent();
  intent.setClass(context, TestWidget.class); //通过intent把广播发给TestWidget本身,TestWidget接受到广播之后,会调用。。进而刷新借鉴  // 。
  intent.setAction(WIDGET_BTN_ACTION);
  PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
  remoteViews.setOnClickPendingIntent(R.id.widget_btn, pendingIntent);//控件btn_widget的点击事件:点击按钮时,会发一个带action的广播。
  appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); //点击完了之后,记得更新一下。
 }

代码解释:
首先需要new一个RemoteViews,构造方法里需要传递两个参数,一个是包名(context.getPacakgeName),一个是布局文件(layout_widget)。
 然后通过remoteViews.setOnClickPendingIntent()设置按钮的点击事件。setOnClickPendingIntent()中需要传递两个参数:一个是id(比如需要被点击的button),一个是PendingIntent。PendingIntent是未来的意图。
 于是我们需要事先构造一个PendingIntent,这个需要通过 PendingIntent.getBroadcast()来构造。getBroadcast()方法中需要传递四个参数,其中有一个是Intent。
 于是我们需要构造一个Intent。在intent里发送广播,并设置Action。
 按钮点击完了之后,记得调用appWidgetManager.updateAppWidget(int[] appWidgetIds, RemoteViews views)方法更新一下,第一个参数就是onUpdate方法中的参数,代表的是所有的控件。

在onUpdate()方法中通过intent发送按钮点击时间的广播之后,我们需要在onReceive()方法中进行广播的接收。
 onReceive()方法中的代码如下:

 @Override
 public void onReceive(Context context, Intent intent) {
  super.onReceive(context, intent);
  if (intent != null && TextUtils.equals(intent.getAction(), WIDGET_BTN_ACTION)) { //当intent不为空,且action匹配成功时,就接收广播,然后点击事件成功
   Log.i(WIDGET_BTN_ACTION, "is clicked");
   //接下来开始做点击事件里面的内容
   RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_widget);//注意:需要【重新】构造一个RemoteViews
   remoteViews.setTextViewText(R.id.widget_tv, "be clicked");
   remoteViews.setTextColor(R.id.widget_tv, Color.RED);
   AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);// 单例模式
   ComponentName componentName = new ComponentName(context, TestWidget.class);
   appWidgetManager.updateAppWidget(componentName, remoteViews);//setText之后,记得更新一下
  }
 }

代码解释:
 当intent的action匹配成功时,开始执行做点击时间之后的setText,不过这里需要重新new 一个 RemoteViews,而不能共用onUpdate()方法中的RemoteViews(这是一个很大的坑)。
 执行完点击事件之后的setText之后,记得调用appWidgetManager.updateAppWidget(ComponentName, RemoteViews)方法,第一个参数为组件名,需要我们自己new一下,第二个参数很好解释。

综合来说,TestWidget.java的完整版代码如下:
Testwidget.java:

 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.graphics.Color;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
/**
 * Created by smyhvae on 2016/9/7.
 */
public class TestWidget extends AppWidgetProvider {
 public static final String WIDGET_BTN_ACTION = "widget_btn_action";
 @Override
 public void onReceive(Context context, Intent intent) {
  super.onReceive(context, intent);
  if (intent != null && TextUtils.equals(intent.getAction(), WIDGET_BTN_ACTION)) { //当intent不为空,且action匹配成功时,就接收广播,然后点击事件成功
   Log.i(WIDGET_BTN_ACTION, "is clicked");
   //接下来开始做点击事件里面的内容
   RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_widget);//注意:需要【重新】构造一个RemoteViews
   remoteViews.setTextViewText(R.id.widget_tv, "be clicked");
   remoteViews.setTextColor(R.id.widget_tv, Color.RED);
   AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);// 单例模式
   ComponentName componentName = new ComponentName(context, TestWidget.class);
   appWidgetManager.updateAppWidget(componentName, remoteViews);//setText之后,记得更新一下
  }
 }
 @Override
 public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
  super.onUpdate(context, appWidgetManager, appWidgetIds);
  RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_widget);//需要构造一个RemoteViews
  Intent intent = new Intent();
  intent.setClass(context, TestWidget.class); //通过intent把广播发给TestWidget本身,TestWidget接受到广播之后,会调用。。进而刷新借鉴  // 。
  intent.setAction(WIDGET_BTN_ACTION);
  PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
  remoteViews.setOnClickPendingIntent(R.id.widget_btn, pendingIntent);//控件btn_widget的点击事件:点击按钮时,会发一个带action的广播。
  appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); //点击完了之后,记得更新一下。
 }
}

运行之后,把widget拖到桌面上,效果如下:

点击按钮后,效果如下:

工程文件:(Android Studio 2.1)

当然,widget还有很多其他的用途。比如:
 •与Service进行通信
 •widget控件的交互方法。
 •如何做一个桌面播放器Widget

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android编程之桌面小部件AppWidgetProvider用法示例

    本文实例讲述了Android编程之桌面小部件AppWidgetProvider用法.分享给大家供大家参考,具体如下: /** * 桌面小部件 AppWidget配置 * * @description: * @author ldm * @date 2016-5-16 下午1:57:16 */ public class ExampleAppWidgetConfigure extends Activity { static final String TAG = "ExampleAppWidgetCon

  • Android学习之AppWidget高级效果

    接着AppWidget基础学习,今天是一个"进阶版"的小例子,用来检验一下自己的学习效果.于是就做了一个掷骰子的Widget. 方便大家观看,先截图如下: 需要注意的是在drawable文件夹下有几张图片,我是在网上下载的别人的素材. 下面就开始我们的学习之旅吧. 第一步: 是在res/目录下创建一个名为xml的文件夹(其实名字是随意的,不必拘泥与这一个名字),然后在里面创建一个appwidget_info.xml文件,其作用就是向系统进行声明. <appwidget-provi

  • Android之AppWidget(桌面小部件)开发浅析

    什么是AppWidget AppWidget 即桌面小部件,也叫桌面控件,就是能直接显示在Android系统桌面上的小程序,先看图: 图中我用黄色箭头指示的即为AppWidget,一些用户使用比较频繁的程序,可以做成AppWidget,这样能方便地使用.典型的程序有时钟.天气.音乐播放器等.AppWidget 是Android 系统应用开发层面的一部分,有着特殊用途,使用得当的化,的确会为app 增色不少,它的工作原理是把一个进程的控件嵌入到别外一个进程的窗口里的一种方法.长按桌面空白处,会出现

  • 基于Android AppWidgetProvider的使用介绍

    AppWidgetProvider 用来在HOME页面显示插件 实现步骤:1.为AppWidget提供一个元布局文件AppWigdetProvider_Provider.xml,用来显示Widget的界面.2.创建一个类继承自AppWidgetProvider,并覆写里面的相关的方法.3.为WidgetProvider创建一个引用的布局文件,或者直接用main.xml.4.在程序中注册Manifest.xml. 代码如下: 1.在res/xml/文件夹下创建AppWigdetProvider_P

  • Android学习之AppWidget笔记分享

    什么是AppWidget?AppWidget就是我们平常在桌面上见到的那种一个个的小窗口,利用这个小窗口可以给用户提供一些方便快捷的操作. 今天的目标就是怎么创建一个简单的AppWidget. 首先我先把目录结构展示一下,方便大家理解. 第一步:我们需要在res目录下创建一个folder,可以命名为xml(但这并不是必须的,你也可以换成你喜欢的名字).然后在这么目录下创建一个xml文件.我的appwidget.xml文件代码如下: <appwidget-provider xmlns:androi

  • Android开发入门之Appwidget用法分析

    本文实例讲述了Android Appwidget用法.分享给大家供大家参考,具体如下: App Widgets 是一个小型应用程序的View  他可以嵌入到其他应用程序中(如 桌面程序) 并且可以得到周期性刷新. 在创建App Widget之前需要了解以下几个概念 AppWidgetProviderInfo对象 它是对App Widget 元数据的一个描述,譬如 AppWidget的布局,刷新频率,以及   AppWidgetProvider 类  这些元数据都是定义在XML中. AppWidg

  • 简单掌握Android Widget桌面小部件的创建步骤

    一.Widget设计步骤 需要修改三个XML,一个class: 1.第一个xml是布局XML文件(如:main.xml),是这个widget的.一般来说如果用这个部件显示时间,那就只在这个布局XML中声明一个textview就OK了. 2.第二个xml是widget_provider.xml,主要是用于声明一个appwidget的.其中,Layout就是指定上面那个main.xml. 3.第三个xml是AndroidManifest.xml,注册broadcastReceiver信息. 4.最后

  • Android中的AppWidget入门教程

    什么是AppWidget?AppWidget就是我们平常在桌面上见到的那种一个个的小窗口,利用这个小窗口可以给用户提供一些方便快捷的操作.本篇打算从以下几个点来介绍AppWidget: 1.如何创建一个简单的AppWidget 2.如何使得AppWidget与客户端程序交互 创建简单的AppWidget 在介绍之前给大家看一下程序运行的最后结果和项目结构图,以便大家有个整体的印象. 运行结果图: 项目结构图: 第一步: 首先在res文件夹下新建一个名字为xml的文件夹,然后在xml目录下创建一个

  • 讲解Android中的Widget及AppWidget小工具的创建实例

    1.Widget .App Widget .Web App 的概念 Widget最初的概念是98年一个叫Rose的苹果工程师提出,直到2003年的时候才正式为大家所知,不过随后无数大公司都开始接受并应用这一思路. 现在我们看到在苹果系统里按下F4弹出的Dashboard里的小工具叫Widget,在Windows 7里侧边栏上的那些漂亮的小工具叫Gadget(widget变体?),除此以外还有yahoo Widget等等Widget产品.他们有一个共同的特点就是采用前台Web开发用的技术(譬如HT

  • Android UI组件AppWidget控件入门详解

    Widget引入 我们可以把Widget理解成放置在桌面上的小组件(挂件),有了Widget,我们可以很方便地直接在桌面上进行各种操作,例如播放音乐. 当我们长按桌面时,可以看到Widget选项,如下图所示: 点击上图中箭头处的widgets图标,会出现如下界面:(都是widget) 长按上图中的任意一个widget,就可以将其放到桌面上. Widget的使用 Widget的实现思路  (1)在AndroidManifest中声明AppWidget:  (2)在xml目录中定义AppWidget

  • android水平循环滚动控件使用详解

    本文实例为大家分享了android水平循环滚动控件的具体代码,供大家参考,具体内容如下 CycleScrollView.java package com.example.test; import android.content.Context; import android.graphics.Rect; import android.os.Handler; import android.util.AttributeSet; import android.view.GestureDetector;

  • android九宫格锁屏控件使用详解

    本文实例为大家分享了android九宫格锁屏控件的具体代码,供大家参考,具体内容如下 代码: public class LockView extends View {     //半径     private int radius;     //中心小圆半径     private int smallRadius;     //一行个数     private int column;     //选中颜色     private int selectColor;     //未选中颜色    

  • Android自定义弹窗提醒控件使用详解

    Android中原生的Dialog弹窗提醒控件样式单一,有时候并不能满足我们的项目需求,而且一个工程里面有时候会在多处都用到弹窗提醒的功能,代码会出现大量的冗余,工作之余,就自己实现了这么一个弹窗提醒控件.自定义控件继承自我们的Dialog,样式自定义,弹窗中的文字可通过数组参数初始化,Item个数实现了动态添加,和数组长度一致.对话框底端可展示一个Item(如:确定)或两个Item(如:确定   取消),通过参数设置.废话不多说,直接上代码: 1.自定义对话框的背景样式,在res/values

  • Android消息个数提醒控件使用详解

    前言 在QQ中有消息个数提醒的控件,虽然现在没用到,但是以后可能会用到,所以就实现它,也不难. 实现 效果图如下: 先贴源码了: public class TipNumberView extends TextView { private Paint mBgPaint ; PaintFlagsDrawFilter pfd; public TipNumberView(Context context, AttributeSet attrs) { super(context, attrs); //初始化

  • WinForm入门与基本控件使用详解

    目录 一.Winform入门 1.WinForm项目结构 2.窗口设计与控件布局 3.窗口事件 4.时间显示器小练习 二.WinForm布局开发 1. 手动布局解决自适应问题 2.WinForm布局属性 3.WinForm布局器 三.WinForm常用控件 1.界面展示 2.实体类 Student(封装信息) 3.逻辑事件代码Form.cs 四.图片框与项目资源 1.添加资源 2.图片框控件展示 一.Winform入门 WinForm 是 Windows Form 的简称,是基于 .NET Fr

  • Android 仿淘宝、京东商品详情页向上拖动查看图文详情控件DEMO详解

    一.淘宝商品详情页效果 我们的效果 二.实现思路 使用两个scrollView,两个scrollView 竖直排列,通过自定义viewGroup来控制两个scrollView的竖直排列,以及滑动事件的处理.如下图 三.具体实现 1.继承viewGroup自定义布局View 重写onMeasure()和onLayout方法,在onLayout方法中完成对两个子ScrollView的竖直排列布局,代码如下: 布局文件: <RelativeLayout xmlns:android="http:/

  • android之SeekBar控件用法详解

    MainActivity.java package com.example.mars_2400_seekbar; import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBar; import android.support.v4.app.Fragment; import android.app.Activity; import android.os.Bundle; import a

  • Android仿京东淘宝自动无限循环轮播控件思路详解

    在App的开发中,很多的时候都需要实现类似京东淘宝一样的自动无限轮播的广告栏,所以就自己写了一个,下面是我自定义控件的思路和过程. 一.自定义控件属性 新建自定义控件SliderLayout继承于RelativeLayout,首先要考虑的就是自定义的控件需要扩展那些属性,把这些属性列出来.在这里是要实现类似于京东淘宝的无限轮播广告栏,那么首先想到的就是轮播的时长.轮播指示器的样式等等.我在这里列举了一些并且结合到了代码中. 1.扩展属性 (1)是否开启自动轮播的功能. (2)指示器的图形样式,一

  • android之RatingBar控件用法详解

    MainActivity.java package com.example.mars_2500_ratingbar; import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBar; import android.support.v4.app.Fragment; import android.app.Activity; import android.os.Bundle; import

随机推荐