RemoteViews用法二:可以接收点击事件并改变外观的widget

关于widget简单的用法参考:RemoteViews用法一:widget简单用法

这篇博客完成一个可以接收点击事件并改变外观的widget,并简要总结,最后附上源码下载地址。

Demo代码:

1.定义Widget布局XML                     /res/layout/widget_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/widget_start"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="start" />
    <Button
        android:id="@+id/widget_stop"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="stop" />

    <TextView
        android:id="@+id/widget_text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="text"
        android:textColor="#fff" />

</LinearLayout>

2.定义Widget属性文件         /res/xml/widget_info.xml  这里不附代码

3. 创建FirstWidgetProvider子类,实现onUpdate()等函数。

package net.qingtian.appwidget2;

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;

/**
 * AppWidgetProvider子类
 * @author qingtian 2014年11月21日15:02:53
 */
public class FirstWidgetProvider extends AppWidgetProvider {

	private static final String TAG = "qingtian";
	// 定义一个常量字符串,该常量用于命名Action
	private static final String UPDATA_STATUS_FROM_WIDGET_START = "net.qingtian.UPDATA_STATUS_FROM_WIDGET_START";
	private static final String UPDATA_STATUS_FROM_WIDGET_STOP = "net.qingtian.UPDATA_STATUS_FROM_WIDGET_STOP";

	@Override
	public void onReceive(Context context, Intent intent) {
		Log.i(TAG, "onReceive");

		String action = intent.getAction();
		if (UPDATA_STATUS_FROM_WIDGET_START.equals(action)) {
			// 改变widget外观
			setViewStatus(context, 1);
		} else if (UPDATA_STATUS_FROM_WIDGET_STOP.equals(action)) {
			// 改变widget外观
			setViewStatus(context, 0);
		} else {
			super.onReceive(context, intent);// 这里一定要添加,eles部分,不然,onReceive不会去调用其它的方法。但是如果把这条语句放在外面,就会每次运行onUpdate,onDeleted等方法,就会运行两次,因为UPDATE_ACTION.equals(action)配置成功会运行一次,super.onReceive(context,
												// intent)配置成功又会运行一次,后都是系统自定义的。
		}
	}

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		Log.i(TAG, "onupdated");

		RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
				R.layout.widget_layout);

		// 设置开始监听
		Intent intentStart = new Intent();
		// 为Intent对象设置Action
		intentStart.setAction(UPDATA_STATUS_FROM_WIDGET_START);
		// 使用getBroadcast方法,得到一个PendingIntent对象,当该对象执行时,会发送一个广播
		PendingIntent pendingIntentStart = PendingIntent.getBroadcast(context,
				0, intentStart, 0);
		remoteViews.setOnClickPendingIntent(R.id.widget_start,
				pendingIntentStart);

		// 设置停止监听
		Intent intentStop = new Intent();
		// 为Intent对象设置Action
		intentStop.setAction(UPDATA_STATUS_FROM_WIDGET_STOP);
		// 使用getBroadcast方法,得到一个PendingIntent对象,当该对象执行时,会发送一个广播
		PendingIntent pendingIntentStop = PendingIntent.getBroadcast(context,
				0, intentStop, 0);
		remoteViews
				.setOnClickPendingIntent(R.id.widget_stop, pendingIntentStop);

		appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
		super.onUpdate(context, appWidgetManager, appWidgetIds);
	}

	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		Log.i(TAG, "onDeleted");
		super.onDeleted(context, appWidgetIds);
	}

	@Override
	public void onDisabled(Context context) {
		Log.i(TAG, "onDisabled");
		super.onDisabled(context);
	}

	@Override
	public void onEnabled(Context context) {
		Log.i(TAG, "onEnabled");
		super.onEnabled(context);
	}

	/**
	 * 设置widget的状态,即改变textView里面的文字
	 *
	 * @param status
	 */
	public void setViewStatus(Context context, int status) {
		RemoteViews remoteViews = null;
		if (status == 0) {// 结束
			remoteViews = new RemoteViews(context.getPackageName(),
					R.layout.widget_layout);
			remoteViews.setTextViewText(R.id.widget_text, "0       结束");
		} else if (status == 1) {// 开始
			remoteViews = new RemoteViews(context.getPackageName(),
					R.layout.widget_layout);
			remoteViews.setTextViewText(R.id.widget_text, "1      开始");
		} else {
			return;
		}
		// remoteViews.setTextViewText(R.id.test_text, "data  "+data);
		// getInstance(Context context) Get the AppWidgetManager instance to
		// use for the supplied Context object.静态方法。
		AppWidgetManager appWidgetManager = AppWidgetManager
				.getInstance(context);
		ComponentName componentName = new ComponentName(context,
				FirstWidgetProvider.class);
		appWidgetManager.updateAppWidget(componentName, remoteViews);
	}

}

4.在manifest中注册receiver,添加一个action为
android.appwidget.action.APPWIDGET_UPDATE 的IntentFilter,并添加如下<meta- data>标识:

<receiver
            android:name="net.qingtian.appwidget2.FirstWidgetProvider"
            android:label="wid2" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="net.qingtian.UPDATA_STATUS_FROM_WIDGET_START" />
                <action android:name="net.qingtian.UPDATA_STATUS_FROM_WIDGET_STOP" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_info" >
            </meta-data>
 </receiver>

总结:

1.关于事件处理的大体流程:由于widget和原来的程序是相对独立的,所以它的事件监听也有些与众不同,主要就是广播的来传递消息。大体分为两步:a.设置widget里的组件被点击后发送广播。b.我们写的AppWidgetProvider的子类可以接收这些广播,然后响应事件,比如改变widget外观,改变service的状态等。

2.关于设置widget里的组件的onclick事件监听:通过widget的生命周期来看,初始化widget里组件的事件监听放在onUpdate方法里。步骤为:构造RemoteViews->为RemoteViews里的组件设置onClick事件->把RemoteViews与widget关联。在这个demo里,我为组件添加的事件监听处理是发送广播。

3.关于接收这些广播,首先AppWidgetProvider就是继承自BroadcastReceiver,只是它默认处理了一些和widget的广播,我们需要去重写onRecevie,但是要保证不能影响他处理默认的广播的功能。

4.在给widget里的组件设置监听时,用到RemoteViews,由于RemoteViews的特殊性,所以设置的代码和平时设置监听的代码有点区别,而且能设置的事件监听类型也比较有限,具体区别参考RemoteViews

源码下载:

http://download.csdn.net/detail/u011647962/8184179

时间: 2024-10-10 10:27:48

RemoteViews用法二:可以接收点击事件并改变外观的widget的相关文章

微信小程序开发(二)点击事件

接着上篇博客继续. 如下修改: // index.wxml <view>Hello World!</view> <button bindtap="but">点击按钮</button> // 按钮 bindtap属性就是添加点击事件,名字是but // index.js Page({ but: function(){ // 通过but点击事件触发后面的函数 console.log("你好") } }) 保存代码后,点击按

RemoteViews用法三:包含的widget的类音乐播放器

关于widget的用法参考:RemoteViews用法一:widget简单用法 RemoteViews用法二:可以接收点击事件并改变外观的widget 这篇博文主要是完成一个类音乐播放器,全面的应用activity,widget,service这几个类. 下载: 代码不算少,就不在这里粘代码了,先把源码下载地址奉上:http://download.csdn.net/detail/u011647962/8184423 demo效果: 为什么这个demo叫类音乐播放器呢,因为只有播放器的形,没有播放

ListView的Item点击事件(消息传递)

转载请保留原文出处“http://my.oschina.net/gluoyer/blog”,谢谢! 您可以到博客的“友情链接”中,“程序猿媛(最新下载)*.*”下载最新版本,持续更新!当前版本,也可直接点击“当前1.5版本”下载.     引子:自定义ListView的Adapter,给Item中的子控件(按钮.图标.文字等)添加点击事件,来进行点击后的不同处理,是经常要做的事情.但有些需要在处理事件中,对Activity中其他控件进行更新的话,通常把Adapter在Activity中实现,处理

CoreText实现图文混排之点击事件-b

CoreText实现图文混排之点击事件 主要思路 我们知道,CoreText是基于UIView去绘制的,那么既然有UIView,就有 -(void)touchesBegan:(NSSet<UITouch *> )touches withEvent:(UIEvent )event方法,我们呢,就是基于这个方法去做点击事件的. 通过touchBegan方法拿到当前点击到的点,然后通过坐标判断这个点是否在某段文字上,如果在则触发对应事件. 上面呢就是主要思路.接下来呢,我们来详细讲解一下.还是老规矩

Unity3D研究院之将UI的点击事件渗透下去(转)

转自 http://www.xuanyusong.com/archives/4241 处理UI还有3D模型的点击推荐使用UGUI的这套事件系统,因为使用起来比较简洁,不需要自己用代码来发送射线,并且可以很好的处理同时点击UI和3D模型上. 1.给3D摄像机挂一个Physics Raycaster组件.Event Mask过滤掉UI. 2.用unity自带的Event Trigger 或者  http://www.xuanyusong.com/archives/3325 就可以对UI 或者 3D模

CoreText实现图文混排之点击事件

今天呢,我们继续把CoreText图文混排的点击事件补充上,这样我们的图文混排也算是圆满了. 哦,上一篇的链接在这里 http://www.jianshu.com/p/6db3289fb05d CoreText实现图文混排.所有需要用到的准备知识都在上一篇,没有赶上车的朋友可以去补个票~ 上正文. CoreText做图文混排之点击事件 主要思路 我们知道,CoreText是基于UIView去绘制的,那么既然有UIView,就有 -(void)touchesBegan:(NSSet)touches

iOS 为移动中的UIView(UIButton )添加点击事件

高高兴兴迎接新的产品新需求,满心欢喜的开始工作,结果研究了一下午才发现,是自己想的太简单了,是我太单纯呀. 需求是这样的类似下雪的效果,随机产生一些小雪花,然后每个雪花可以点击到下个页面. 接到需求之后我的首先想法就是用button实现不久可以了,多简单点事情,结果实践之后就知道自己多么的无知了,在移动中的button根本没有办法接收点击事件. 然后同事给出了一种解决办法,通过手势获取点击的位置,然后遍历页面上的控件,如果在这个范围内就点击成功.通过这个想法我尝试用frame来实现需求,然后发现

Android实例-手机安全卫士(十二)-制作输入密码对话框并设置相应点击事件

一.目标. 自定义输入密码对话框,根据输入的密码与保存着的密码进行判断. 二.代码实现. 1. 采用第十节的方法自定义一个输入密码的对话框. 2.为按钮设置点击事件,主要介绍“确认”按钮的点击事件. ①.通过TextView对象的getText()得到文本并通过toString()转成字符串再通过trim()去除空格,得到String对象的输入密码: ②.通过SharedPreferences对象的getString(String key, String defValue)获得保存着的密码,参数

揭开RecyclerView的神秘面纱(二):处理RecyclerView的点击事件

前言 上一篇文章揭开RecyclerView的神秘面纱(一):RecyclerView的基本使用中,主要讲述了RecyclerView的基本使用方法,不同的布局管理器而造成的多样化展示方式,展示了数据之后,一般都会与用户进行交互,因此我们需要处理用户的点击事件.在ListView和GridView提供了onItemClickListener这个监听器,然而我们查找RecyclerView的API却没有类似的监听器,因此我们需要自己手动处理它的点击事件. 以下提供两种方法来实现处理Recycler