在上篇博客中讲了widget最简单最基本的用法,然而实际项目中可能更多的使用复杂布局控件(如ListView,GridView等的控件)到widget中去,这就需要我们对这些控件做适配了。RemoteView有个setRemoteAdapter的方法可以绑定widget及其实现数据适配器的service类,就是我们后面要讲到的RemoteViewsService, 在这个RemoteViewsService的子类里面调用RemoteViewsFactory 的onGetViewFactory 方法返回一个RemoteViewsFactory 的自定义子类。
下面贴一张RemoteView的原理图,就能就其实现的思路一目了然了。
(图片转载)
从图中看不难理解,widget在复杂布局中通过RemoteView(远程控件)的服务类RemoteViewsService去调用RemoteViewFactory类的方法进行布局适配。
把步骤简单罗列下来就是:
1.AppWidgetProvider子类中,onupdate方法内部声明RemoteView对象并加载Widget的布局文件; 声明并实例化一个intent对象(把remoteViewService子类传给第二个参数),remoteView对象调用setRemoteAdapter方法绑定给remoteViewService对象。
2.RemoteViewService子类中,只需要调用一个RemoteViewsFactory的onGetViewFactory方法把remoteViewsFactory的子类回传。
3.RemoteViewsFactory子类中,干着原本ListView的BaseAdapter类似的活儿。这个类内部的oncreate方法一般进行参数的赋值;getCount方法和BaseAdapter类里面的getCount是一样的,返回Widget中ListView或者GirdView的item数目;getViewAt(int position)方法内执行item的赋值操作,其作用就类似而BaseAdapter类内部的getView方法。
接下来直接上代码,从代码来看整个流程的思路。
第一步:两个xml文件,(widget_layout.xml 和 widget_info.xml)
res/layout/widget_layout.xml中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="vertical"
android:gravity="center_horizontal"
android:background="@drawable/dialog_loading_bg">
<ListView
android:id=