android之Widget开发详解实例二

下面是本篇的大纲:1、AppWidget 框架类2、AppWidget 框架的主要类介绍3、DEMO 讲解1、AppWidget 框架类1、AppWidgetProvider :继承自 BroadcastRecevier , 在AppWidget 应用 update、enable、disable 和 delete 时接收通知。其中,onUpdate、onRece

大家好,又见面了,我是全栈君。

下面是本篇的大纲:

  • 1、AppWidget 框架类
  • 2、AppWidget 框架的主要类介绍
  • 3、DEMO 讲解

1、AppWidget 框架类

  • 1、AppWidgetProvider :继承自 BroadcastRecevier , 在AppWidget 应用 update、enable、disable 和 delete 时接收通知。其中,onUpdate、onReceive 是最常用到的方法,它们接收更新通知。
  • 2、 AppWidgetProvderInfo:描述 AppWidget 的大小、更新频率和初始界面等信息,以XML 文件形式存在于应用的 res/xml/目录下。
  • 3、AppWidgetManger :负责管理 AppWidget ,向 AppwidgetProvider 发送通知。
  • 4、RemoteViews :一个可以在其他应用进程中运行的类,向 AppWidgetProvider 发送通知。

2、AppWidget 框架的主要类介绍

 1) AppWidgetManger 类

  • bindAppWidgetId(int appWidgetId, ComponentName provider)
    通过给定的ComponentName 绑定appWidgetId
  • getAppWidgetIds(ComponentName provider)
    通过给定的ComponentName 获取AppWidgetId
  • getAppWidgetInfo(int appWidgetId)
    通过AppWidgetId 获取 AppWidget 信息
  • getInstalledProviders()
    返回一个List<AppWidgetProviderInfo>的信息
  • getInstance(Context context)
    获取 AppWidgetManger 实例使用的上下文对象
  • updateAppWidget(int[] appWidgetIds, RemoteViews views)
    通过appWidgetId 对传进来的 RemoteView 进行修改,并重新刷新AppWidget 组件
  • updateAppWidget(ComponentName provider, RemoteViews views)
    通过 ComponentName 对传进来的 RemoeteView 进行修改,并重新刷新AppWidget 组件
  • updateAppWidget(int appWidgetId, RemoteViews views)
    通过appWidgetId 对传进来的 RemoteView 进行修改,并重新刷新AppWidget 组件

2) 继承自 AppWidgetProvider 可实现的方法为如下:

  • 1、onDeleted(Context context, int[] appWidgetIds)
  • 2、onDisabled(Context context)
  • 3、onEnabled(Context context)
  • 4、onReceive(Context context, Intent intent)
    Tip:因为 AppWidgetProvider 是继承自BroadcastReceiver  所以可以重写onRecevie 方法,当然必须在后台注册Receiver
  • 5、onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
  • 一般来说都是重写onUpdate就够了
  • 3、Demo讲解

    下面是我今天做的一个实例,提供给大家练习时做参考,效果如下:在布局中放一个 TextView 做桌面组件,然后设置TextView 的 Clickable=”true” 使其有点击的功能,然后我们点击它时改变它的字体,再点击时变回来,详细操作如下流程:

    • 1、新建AppWidgetProvderInfo
    • 2、写一个类继承自AppWidgetProvider
    • 3、后台注册Receiver
    • 4、使 AppWidget 组件支持点击事件
    • 5、如何使TextView 在两种文本间来回跳转

    问题抛出来了,那么一起解决它吧。

    1、新建AppWidgetProvderInfo

    代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:minWidth="60dp"
        android:minHeight="30dp"
        android:updatePeriodMillis="86400000"
        android:initialLayout="@layout/main">
    </appwidget-provider>

    Tip:上文说过AppWidgetProvderInfo 是在res/xml 的文件形式存在的,看参数不难理解,就是定义widget的大小和更新频率等信息,比较重要的是这里android:initialLayout=”@layout/main” 此句为指定桌面组件的布局文件,即规划widget里面有哪些组件,如何排列等。

  • 2、写一个类继承自AppWidgetProvider

    代码如下:

    package com.terry;
    public class widgetProvider extends AppWidgetProvider {
    	private static final String CLICK_NAME_ACTION = "com.terry.action.widget.click";
    	public static boolean isChange=true;
    	private static RemoteViews rv;
    
    	@Override
    	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
    			int[] appWidgetIds) {
    		// TODO Auto-generated method stub
    		final int N = appWidgetIds.length;
    		for (int i = 0; i < N; i++) {
    			int appWidgetId = appWidgetIds[i];
    			updateAppWidget(context, appWidgetManager, appWidgetId);
    		}
    	}
    
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		// TODO Auto-generated method stub
    		super.onReceive(context, intent);
    
    		if (rv == null) {
    			rv = new RemoteViews(context.getPackageName(), R.layout.main);
    		}
    		if (intent.getAction().equals(CLICK_NAME_ACTION)) {
    			if (isChange) {
    				rv.setTextViewText(R.id.TextView01, context.getResources()
    						.getString(R.string.load));
    
    			} else {
    				rv.setTextViewText(R.id.TextView01, context.getResources()
    						.getString(R.string.change));
    
    			}
    			Toast.makeText(context, Boolean.toString(isChange),
    					Toast.LENGTH_LONG).show();
    			isChange = !isChange;
    
    		}
    		AppWidgetManager appWidgetManger = AppWidgetManager
    				.getInstance(context);
    		int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName(
    				context, widgetProvider.class));
    		appWidgetManger.updateAppWidget(appIds, rv);
    	}
    
    	public static void updateAppWidget(Context context,
    			AppWidgetManager appWidgeManger, int appWidgetId) {
    		rv = new RemoteViews(context.getPackageName(), R.layout.main);
    		Intent intentClick = new Intent(CLICK_NAME_ACTION);
    		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
    				intentClick, 0);
    		rv.setOnClickPendingIntent(R.id.TextView01, pendingIntent);
    		appWidgeManger.updateAppWidget(appWidgetId, rv);
    	}
    }

    重写两个方法:1.onUpdate 为组件在桌面上生成时调用,并更新组件UI,

  •                        2.onReceiver 为接收广播时调用更新UI,一般这两个方法是比较常用的。

  • 3、后台注册Receiver

    后台配置文件代码如下:

    <receiver android:name=".widgetProvider">
    			<meta-data android:name="android.appwidget.provider"
    				android:resource="@xml/appwidget_provider"></meta-data>
    			<intent-filter>
    				<action android:name="com.terry.action.widget.click"></action>
    				<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    				 
    			</intent-filter>
    </receiver>

    Tip:因为是桌面组件,所以暂时不考虑使用Activity 界面,当然你在实现做项目时可能会需要点击时跳转到Activity 应用程序上做操作,典型的案例为Android  提供的音乐播放器。

  • 上面代码中比较重要的是这一句 <meta-data android:name=”android.appwidget.provider”  android:resource=”@xml/appwidget_provider”></meta-data>

  • 大意为指定桌面应用程序的AppWidgetProvderInfo 文件,使其可作其管理文件,管理widget的大小更新时间等信息.

    4、使 AppWidget 组件支持点击事件

    先看代码:

    public static void updateAppWidget(Context context,
    			AppWidgetManager appWidgeManger, int appWidgetId) {
    		rv = new RemoteViews(context.getPackageName(), R.layout.main);
    		Intent intentClick = new Intent(CLICK_NAME_ACTION);
    		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
    				intentClick, 0);
    		rv.setOnClickPendingIntent(R.id.TextView01, pendingIntent);
    		appWidgeManger.updateAppWidget(appWidgetId, rv);
    	}

    此方法为创建组件时 onUpdate 调用的更新UI的方法,代码中使用RemoteView 找到组件的布局文件,同时为其设置广播接收器CLICK_NAME_ACTION并且通过RemoteView 的setOnClickPendingIntent 方法找到我想触发事件的TextView 为其设置广播。接着

    @Override
    	public void onReceive(Context context, Intent intent) {
    		// TODO Auto-generated method stub
    		super.onReceive(context, intent);
    
    		if (rv == null) {
    			rv = new RemoteViews(context.getPackageName(), R.layout.main);
    		}
    		if (intent.getAction().equals(CLICK_NAME_ACTION)) {
    			if (isChange) {
    				rv.setTextViewText(R.id.TextView01, context.getResources()
    						.getString(R.string.load));
    
    			} else {
    				rv.setTextViewText(R.id.TextView01, context.getResources()
    						.getString(R.string.change));
    
    			}
    			Toast.makeText(context, Boolean.toString(isChange),
    					Toast.LENGTH_LONG).show();
    			isChange = !isChange;
    
    		}
    		AppWidgetManager appWidgetManger = AppWidgetManager
    				.getInstance(context);
    		int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName(
    				context, widgetProvider.class));
    		appWidgetManger.updateAppWidget(appIds, rv);
    	}

    在onReceiver 中通过判断识别传进来的广播来触发动作。
    5、如何使TextView 在两种文本间来回跳转

  • 如果你发现无法实现文本的跳转变化,尝试把public static boolean isChange=true;这个boolean放在新建一个类里面试试看.

  • 还有main.xml的代码如下:

  • <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    	android:orientation="vertical" 
    	android:layout_width="fill_parent"
    	android:id="@+id/layout" 
    	android:layout_height="fill_parent">
    
    	<TextView android:text="@string/load" 
    	          android:id="@+id/TextView01"
    		      android:clickable="true"
    		      android:layout_width="wrap_content" 
    		      android:layout_height="wrap_content"></TextView>
    </LinearLayout>
    

     

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/121419.html原文链接:https://javaforall.net

(0)
上一篇 2022年3月10日 下午2:00
下一篇 2022年3月10日 下午2:00


相关推荐

  • Idea激活码最新教程2020.1.3版本,永久有效激活码,亲测可用,记得收藏

    Idea激活码最新教程2020.1.3版本,永久有效激活码,亲测可用,记得收藏Idea 激活码教程永久有效 2020 1 3 激活码教程 Windows 版永久激活 持续更新 Idea 激活码 2020 1 3 成功激活

    2025年5月23日
    55
  • java inputstream和outputstream_java input

    java inputstream和outputstream_java input原文地址:http://www.zgljl2012.com/javaji-chu-inputstream-inputstreamreaderhe-bufferedreader/在Java中,上述三个类经常用于处理数据流,下面介绍一下三个类的不同之处以及各自的用法。InputStream:是所有字节输入流的超类,一般使用它的子类:FileInputStream等,它能输出字节流;…

    2026年4月14日
    5
  • java for怎么跳出_java跳出for循环的方法

    java for怎么跳出_java跳出for循环的方法java 跳出 for 循环的方法发布时间 2020 06 2615 56 42 来源 亿速云阅读 193 作者 Leah 这篇文章将为大家详细讲解有关 java 跳出 for 循环的方法 文章内容质量较高 因此小编分享给大家做个参考 希望大家阅读完这篇文章后对相关知识有一定的了解 break 语句 break 用于完全结束一个循环 跳出循环体 不管是哪种循环 一旦在循环体中遇到 break 系统将完全结束循环 开始执行循

    2026年3月17日
    1
  • linux系统线程通信的几种方式,Linux的进程/线程通信方式总结

    linux系统线程通信的几种方式,Linux的进程/线程通信方式总结Linux系统中的进程通信方式主要以下几种:同一主机上的进程通信方式*UNIX进程间通信方式:包括管道(PIPE),有名管道(FIFO),和信号(Signal)*SystemV进程通信方式:包括信号量(Semaphore),消息队列(MessageQueue),和共享内存(SharedMemory)网络主机间的进程通信方式*RPC:RemoteProcedureCall…

    2022年6月20日
    48
  • Java集合汇总篇「建议收藏」

    Java集合汇总篇「建议收藏」一.集合框架Java集合框架一些列的接口和类来实现很多常见的数据结构和算法,例如LinkedList就是集合框架提供的实现了双向链表的数据结构,关于这一篇文章建议大家收藏,我会不断地完善和扩充它的内容,例如最下面的系列文章我以后也会对它进行不断的更新集合框架的接口集合框架提供了很多接口,这些接口都包含了特定的方法来实现对集合上的特定操作)我们将要学习这些接口以及子接口和它们的各种实现类,在开始之前我们先简单学习一下这些广泛运用的接口,可以看到整个集合框架,总共有三个顶级接口Collecti

    2022年7月16日
    18
  • 详解DOM对象中clientWidth、offsetWidth等属性

    详解DOM对象中clientWidth、offsetWidth等属性我们有时需要获得鼠标在某盒子中的位置,或者是随意移动某盒子的位置,在这些场景中我们可能经常需要用到clientWidth、offsetWidth、offsetTop啊等等。但是对于初学者来说(包括我),看到这些就头疼,因为感觉意思都相近,但作用却不同,所以今天天我就来捋一捋,搞清楚,后面好干活。好吧,废话不多说,开始吧。先上一下示例代码,下面要用到。HTML:…

    2022年7月22日
    12

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号