Android Widget 开发详解(二) +支持listView滑动的widget
转载请标明出处:http://blog.csdn.net/sk719887916/article/details/47027263
不少开发项目中都会有widget功能,别小瞧了它,他也是android的七大组件之一,对widget陌生的朋友可以阅读下我的上篇文章< Android Widget工作原理详解(一)>关于内部的介绍,还没掌握的同学不要担心,开发AppWidget套路很简单,今天我们就实现一个可以加入listView滑动的widget,熟悉下一个普通widget的开发步骤。
一 创建AppWidgetProvider
remoteViews)来加载或更新widget布局,也可以通过onReceive()
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // 获取Widget的组件名 ComponentName thisWidget = new ComponentName(context, MyAppListWidgetProvider.class); // 创建一个RemoteView RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.my_widget_layout); // 把这个Widget绑定到RemoteViewsService Intent intent = new Intent(context, MyRemoteViewsService.class); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[0]); // 设置适配器 remoteViews.setRemoteAdapter(R.id.widget_list, intent); // 设置当显示的widget_list为空显示的View remoteViews.setEmptyView(R.id.widget_list, R.layout.none_data); // 点击列表触发事件 Intent clickIntent = new Intent(context, MyAppListWidgetProvider.class); // 设置Action,方便在onReceive中区别点击事件 clickIntent.setAction(clickAction); clickIntent.setData(Uri.parse(clickIntent.toUri(Intent.URI_INTENT_SCHEME))); PendingIntent pendingIntentTemplate = PendingIntent.getBroadcast( context, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setPendingIntentTemplate(R.id.widget_list, pendingIntentTemplate); // 刷新按钮 final Intent refreshIntent = new Intent(context, MyAppListWidgetProvider.class); refreshIntent.setAction("refresh"); final PendingIntent refreshPendingIntent = PendingIntent.getBroadcast( context, 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.button_refresh, refreshPendingIntent); // 更新Wdiget appWidgetManager.updateAppWidget(thisWidget, remoteViews); }
此方功类似广播的onReceive()用发,用开接收和处理广播,如果我们在manifest.xml注册了MyAppListWidgetProvider为一个appwidget,那么不必须为此广播加上widget标示,添加一action:<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />,下面的 <meta-data>标签用来定义widget的属性,指定一个widget描述信息,具体释义请阅读 上篇widget原理详解文章,
<!-- Widget必须添加到manifest文件中,和Broadcaset Receiver一样使用“receiver”标签 --> <receiver android:name=".MyAppListWidgetProvider" > <!-- 此处设置Wdiget更新动作 --> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <!-- 此处设置Widget的描述资源res/xml/my_widget.xml --> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_info" > </meta-data> </receiver>
onReceive里处理代码逻辑,比如我这里用来接收widget的用来更新我们在onUpdate()给刷新按钮定义的点击事件,处理刷新界面需求,
/** * 接收Intent */ @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); String action = intent.getAction(); if (action.equals("refresh")) { // 刷新Widget final AppWidgetManager mgr = AppWidgetManager.getInstance(context); final ComponentName cn = new ComponentName(context, MyAppListWidgetProvider.class); MyRemoteViewsFactory.mList.add("音乐"+i); // 这句话会调用RemoteViewSerivce中RemoteViewsFactory的onDataSetChanged()方法。 mgr.notifyAppWidgetViewDataChanged(mgr.getAppWidgetIds(cn), R.id.widget_list); } else if (action.equals(clickAction)) { // 单击Wdiget中ListView的某一项会显示一个Toast提示。 Toast.makeText(context, intent.getStringExtra("content"), Toast.LENGTH_SHORT).show(); } i=i+1; }
@Override public void onEnabled(Context context) { // TODO Auto-generated method stub super.onEnabled(context); Toast.makeText(context, "用户将widget添加桌面了", Toast.LENGTH_SHORT).show(); }
@Override public void onDeleted(Context context, int[] appWidgetIds) { // TODO Auto-generated method stub。 Toast.makeText(context, "用户将widget从桌面移除了", Toast.LENGTH_SHORT).show(); super.onDeleted(context, appWidgetIds); }
二 创建RemoteViewsFactory
public class MyRemoteViewsFactory implements RemoteViewsFactory { private final Context mContext; public static List<String> mList = new ArrayList<String>(); /* * 构造函数 */ public MyRemoteViewsFactory(Context context, Intent intent) { mContext = context; } /* * MyRemoteViewsFactory调用时执行,这个方法执行时间超过20秒回报错。 * 如果耗时长的任务应该在onDataSetChanged或者getViewAt中处理 */ @Override public void onCreate() { // 需要显示的数据 mList.add(""); for (int i = 0; i < 5; i++) { mList.add("item"+ i); } } /* * 当调用notifyAppWidgetViewDataChanged方法时,触发这个方法 * 例如:MyRemoteViewsFactory.notifyAppWidgetViewDataChanged(); */ @Override public void onDataSetChanged() { } /* * 这个方法不用多说了把,这里写清理资源,释放内存的操作 */ @Override public void onDestroy() { mList.clear(); } /* * 返回集合数量 */ @Override public int getCount() { return mList.size(); } /* * 创建并且填充,在指定索引位置显示的View,这个和BaseAdapter的getView类似 */ @Override public RemoteViews getViewAt(int position) { if (position < 0 || position >= mList.size()) return null; String content = mList.get(position); // 创建在当前索引位置要显示的View final RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.my_widget_layout_item); // 设置要显示的内容 rv.setTextViewText(R.id.widget_list_item_tv, content); // 填充Intent,填充在AppWdigetProvider中创建的PendingIntent Intent intent = new Intent(); // 传入点击行的数据 intent.putExtra("content", content); rv.setOnClickFillInIntent(R.id.widget_list_item_tv, intent); return rv; } /* * 显示一个"加载"View。返回null的时候将使用默认的View */ @Override public RemoteViews getLoadingView() { return null; } /* * 不同View定义的数量。默认为1(本人一直在使用默认值) */ @Override public int getViewTypeCount() { return 1; } /* * 返回当前索引的。 */ @Override public long getItemId(int position) { return position; } /* * 如果每个项提供的ID是稳定的,即她们不会在运行时改变,就返回true(没用过。。。) */ @Override public boolean hasStableIds() { return true; }
三 RemoteViewsService
具体地说,其子类RemoteViewsService是一个远程的服务适配器 可以请求RemoteViews,管理RemoteViews的服务。我们继承RemoteViewsService来获得一个视图工厂,
@TargetApi(Build.VERSION_CODES.HONEYCOMB) public class MyRemoteViewsService extends RemoteViewsService { @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { return new MyRemoteViewsFactory(this.getApplicationContext(), intent); } }
四 增加widet基础属性配置
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/my_widget_layout" android:minHeight="120dp" android:minWidth="280dp" android:previewImage="@drawable/ic_launcher" android:resizeMode="horizontal|vertical" android:updatePeriodMillis="0" > <!-- sdk1.5之后updatePeriodMillis已失效,置为0,循环执行自行在代码中实现。 至于其他属性可以查一下。在其他随笔中我也给出了 --> </appwidget-provider>
2 新建widget资源文件xml
属性来指定。而widget描述信息我们在manifest.xml中 用<meta-data>标签用来指定。
<?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="200dp" android:background="@android:color/white" android:orientation="vertical" > <Button android:id="@+id/button_refresh" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:background="@drawable/lite_widget_item_choosed_background_icon" android:textColor="@android:color/white" android:layout_marginTop="2dp" android:text="刷新" /> <ListView android:id="@+id/widget_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:cacheColorHint="#00000000" android:scrollbars="none" /> <!-- 此处的ListView 可以换成StackView或者GridView --> </LinearLayout>
Android Widget 开发详解(二) +支持listView滑动的widget的更多相关文章
- Android WebView 开发详解(二)
转载请注明出处 http://blog.csdn.net/typename/article/details/39495409 powered by miechal zhao 概览: Androi ...
- Android USB 开发详解
Android USB 开发详解 先附上 Android USB 官方文档 Android通过两种模式支持各种 USB 外设和 Android USB 附件(实现Android附件协议的硬件):USB ...
- JMessage Android 端开发详解
目前越来越多的应用会需要集成即时通讯功能,这里就为大家详细讲一下如何通过集成 JMessage 来为你的 App 增加即时通讯功能. 首先,一个最基础的 IM 应用会需要有哪些功能? 用户注册 / 登 ...
- Android WebView 开发详解
Android WebView 开发详解 参见 http://blog.csdn.net/typename/article/details/39030091
- 《Android游戏开发详解》一1.7 控制流程第1部分——if和else语句
本节书摘来异步社区<Android游戏开发详解>一书中的第1章,第1.7节,译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区"公众号查看. 1.7 ...
- Android Studio 插件开发详解二:工具类
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78112856 本文出自[赵彦军的博客] 在插件开发过程中,我们按照开发一个正式的项 ...
- Android 时间日期Widget 开发详解
桌面Widget其实就是一个显示一些信息的工具(现在也有人开发了一些有实际操作功能的widget.例如相机widget,可以直接桌面拍照).不过总的来说,widget主要功能就是显示一些信息.我们今天 ...
- Android WebView 开发详解(一)
转载请注明出处 http://blog.csdn.net/typename/article/details/39030091 powered by meichal zhao 概览: Android ...
- Android WebView 开发详解(三)
转载请注明出处 http://blog.csdn.net/typename/article/details/40302351 powered by miechal zhao 概览 Android ...
随机推荐
- Java中next()和nextLine()
next()读取到有效字符后才可以结束输入,对输入有效字符之前遇到的空格键.Tab键或Enter键等结束符,next()方法会自动将其去掉,只有在输入有效字符之后,next()方法才将其后输入的空格键 ...
- MongoDB 高级索引
考虑以下文档集合(users ): { "address": { "city": "Los Angeles", "state&qu ...
- HTML DOM 改变 HTML 内容
HTML DOM 允许 JavaScript 改变 HTML 元素的内容. 改变 HTML 输出流 JavaScript 能够创建动态的 HTML 内容: 今天的日期是: Thu Feb 25 201 ...
- Linux基础指令
Linux基础指令 只写了最简单的一些文件操作,基本没有带参数 查看当前目录 pwd 跳转到某路径 cd 查看当前目录下的文件 ls ls -l // -l 查看详细信息 打开当前所在文件夹 open ...
- rbac 概念
1 权限管理 1.1 什么是权限管理 分享牛原创,分享牛系列.基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户 ...
- 网站开发进阶(四十四)input type="submit" 和"button"的区别
网站开发进阶(四十四)input type="submit" 和"button"的区别 在一个页面上画一个按钮,有四种办法: 这就是一个按钮.如果你不写ja ...
- 制作pypi上的安装库
下载地址 如何制作分发工具呢 setuppy 源码包 其他文件 制作过程 首先上场的肯定是setuppy了如下 然后是LICENCE 注册 测试 总结 自从接触Python以来也有几个月了,虽然主要的 ...
- SLAMCN资料收藏转载
网页链接地址:http://www.slamcn.org/index.php/%E9%A6%96%E9%A1%B5 资料非常丰富,内容如下: 首页 目录 [隐藏] 1 SLAM 介绍 1.1 什么是 ...
- [ExtJS5学习笔记]第十三节 Extjs5的Ext.each方法学习
本文地址:http://blog.csdn.net/sushengmiyan/article/details/39009555 sencha官方API:http://docs.sencha.com/e ...
- Centos中git的安装
CentOS的yum源中没有git,只能自己编译安装,现在记录下编译安装的内容,留给自己备忘. 确保已安装了依赖的包 yum install curl yum install curl-deve ...