android4.0中实现AppWidget集合
1.准备appwidget的初始布局和预览视图等资源
AppWidget集合应用时,需配置两种布局文件:一个用于集合view布局显示,一个用于集合view上条目的的布局显示
注意:要设置empty views,以便匹配集合view的空状态,且该View必须是集合View(一般可为ListView、GridView、StackView或AdapterViewFlipper)的同级View
2.在res/xml中创建AppWidgetProviderInfo文件
根标签为appwiget-provider,其属性要包括initialLayout、previewImage、autoAdvanceViewId 等,具体可参考后面的例子
3.创建AppWidgetProvider的实现子类,并在清单文件里面注册引用的元数据和监听的广播action
清单文件中,需给该子类配置如下信息:
action android:name="android.appwidget.action.APPWIDGET_UPDATE"
元数据:android:name="android.appwidget.provider"
代码中,onUpdate方法中完成Widget布局到桌面上时的刷新;onReceive方法中完成接收到特定广播后的Widget刷新
(另外,如果配置了Configure Activity还需要注册action,"android.appwidget.action.APPWIDGET_CONFIGURE")
4.因为是集合Widget,需要创建一个继承了RemoteViewsService的Service子类,并在清单文件中注册权限,阻止其它程序自由访问Widget中的数据
android:permission="android.permission.BIND_REMOTEVIEWS"
代码中通过onGetViewFactory方法返回一个RemoteViewsFactory的实现类,该实现类中的onCreate()用来创建及初始化设置Widget的单个item; getViewAt()方法用来同步数据,进行耗时的更新操作,并返回RemoteView对象。
getViewAt方法中可完成:
<1>将显示独立Widget条目的view item数据以fill-in intent方式填充到集合Widget的View集合中
View集合中Chilid view不允许使用setOnClickPendingIntent的点击事件动态更新,只能通过setOnClickFillInIntent来实现,
即先设置好集合view的pending intent template点击事件模版,然后,将独立的chilid view条目的the fill-in Intent意图事件填充进来。
<2>进行耗时的处理图片和获取网络数据操作,并同步刷新Widget的显示内容。
RemoteViewsFactory的实现类中还有一个onDataSetChanged方法,也可进行耗时的处理图片和获取网络数据操作,但他可以保持Widget的当前状态,直到我们显示调用AppWidgetManager notifyAppWidgetViewDataChanged才会触发
参考: ExampleStackViewAppWidgets
本例主要参考developer.android/resources/samples/StackWidget/index.html
在其基础上略有改进
l
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="schemas.android/apk/res/android"
    android:autoAdvanceViewId="@id/statck_view"
    android:initialLayout="@layout/widget_layout"
    android:minHeight="74dp"
    android:minWidth="290dp"
    android:previewImage="@drawable/doraemon"
    android:updatePeriodMillis="3600000"
    android:resizeMode="vertical">
</appwidget-provider>
StackViewAppWidgetService.java
/**
* 实现了给StackView上ImageView适配背景图片
* @author wgyang
*
*/
public class StackViewAppWidgetService extends RemoteViewsService {
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new ApplicationContext(),
                intent);
    }
}
class ViewFlipperRemoteViewsFactory implements
        RemoteViewsService.RemoteViewsFactory {
    int[] images = { R.drawable.doraemon, R.drawable.baidu, R.drawable.bing,
            le };
    //int[] colors = { Color.BLUE, Color.RED, Color.GRAY, Color.GREEN };
    private static final int mCount = 4;
    private List<ImageView> mImageViews = new ArrayList<ImageView>();
    private Context mContext;
    private static ImageView mImageView;
    public ViewFlipperRemoteViewsFactory(Context context, Intent intent) {
        mContext = context;
    }
    public void onCreate() {
        // In onCreate() you setup any connections / cursors to your data source. Heavy lifting,
        // for example downloading or creating content etc, should be deferred to onDataSetChanged()
        // or getViewAt(). Taking more than 20 seconds in this call will result in an ANR.
        // 因不是很耗时,可放在这里
        //在循环里控制显示独立Widget条目的界面信息
        for (int i = 0; i < mCount; ++i) {
            mImageView = new ImageView(mContext);
            //mImageView.setBackgroundColor(colors[i]);
            //mImageView.setImageResource(images[i]);
            mImageViews.add(mImageView);
        }
          // We sleep for 3 seconds here to show how the empty view appears in the interim.
        // The empty view is set in the StackWidgetProvider and should be a sibling of the
        // collection view.
    }
    public RemoteViews getViewAt(int position) {
          // position will always range from 0 to getCount() - 1.
        // We construct a remote views item based on our widget item xml file, and set the
        // text based on the position.
        //通过Remoteview给view item上设置要显示内容
        RemoteViews rv = new PackageName(),
                R.layout.widget_item);pending
        // rv.setTextViewText(R.id.widget_item,
        // (position).text);
        //rv.setImageViewResource(R.id.widget_item, (position)
        //        .getBackground().getLevel());
        //注意要将单个的widget条目信息设置进rv中,不然刷新界面不成功的
        rv.setImageViewBitmap(R.id.widget_item, BitmapFactory.decodeResource(
                Resources(), images[position]));
        // Next, we set a fill-intent which will be used to fill-in the pending intent template

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。