setRemoteAdapter (int viewId, Intent intent):该方法可以使用 Intent 更新 RemoteViews 中viewId 对应的组件。

上面方法的 Intent 参数应该封装一个 RemoteViewsService 参数,RemoteViewsService 虽然继承了 Service 组件,但它的主要作用是为 RemoteViews 中 viewId 对应的组件提供列表项。

由于Intent参数负责提供列表项,因此viewId参数对应的组件可以是ListView、GridView、StackView 和 AdapterViewFlipper 等,这些组件都是 AdapterView 的子类,由此可见RemoteViewsService 负责提供的对象,应该是一个类似于 Adapter 的对象。

RemoteViewsService 通常用于被继承,继承该基类时需要重写它的 onGetViewFactory()方 法 , 该 方 法 就 需 要 返 回 一 个 类 似 于 Adapterr 对 象 —— 但 不 是 Adapter , 而 是RemoteViewsFactory 对象,RemoteViewsFactory 的功能完全类似于 Adapter。

StackViewWidget实现如下:

StackWidgetService.java

package org.crazyit.desktop;import android.content.Context;import android.content.Intent;import android.widget.RemoteViews;import android.widget.RemoteViewsService;/** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2014, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */public class StackWidgetService extends RemoteViewsService{    // 重写该方法,该方法返回一个RemoteViewsFactory对象。    // RemoteViewsFactory对象的的作用类似于Adapter,    // 它负责为RemoteView中指定组件提供多个列表项。    @Override    public RemoteViewsFactory onGetViewFactory(Intent intent)    {        return new StackRemoteViewsFactory(this.getApplicationContext(),            intent);  //    }    class StackRemoteViewsFactory implements    RemoteViewsService.RemoteViewsFactory    {        // 定义一个数组来保存该组件生成的多个列表项        private int[] items = null;        private Context mContext;        public StackRemoteViewsFactory(Context context, Intent intent)        {            mContext = context;        }        @Override        public void onCreate()        {            // 初始化items数组            items = new int[] { R.drawable.bomb5, R.drawable.bomb6,                R.drawable.bomb7, R.drawable.bomb8, R.drawable.bomb9,                R.drawable.bomb10, R.drawable.bomb11, R.drawable.bomb12,                R.drawable.bomb13, R.drawable.bomb14, R.drawable.bomb15,                R.drawable.bomb16            };        }        @Override        public void onDestroy()        {            items = null;        }        // 该方法的返回值控制该对象包含多少个列表项        @Override        public int getCount()        {            return items.length;        }        // 该方法的返回值控制各位置所显示的RemoteViews        @Override        public RemoteViews getViewAt(int position)        {            // 创建RemoteViews对象,加载/res/layout目录下widget_item.xml文件            RemoteViews rv = new RemoteViews(mContext.getPackageName(),                R.layout.widget_item);            // 更新widget_item.xml布局文件中的widget_item组件            rv.setImageViewResource(R.id.widget_item,                items[position]);            // 创建Intent、用于传递数据            Intent fillInIntent = new Intent();            fillInIntent.putExtra(StackWidgetProvider.EXTRA_ITEM, position);            // 设置当单击该RemoteViews时传递fillInIntent包含的数据            rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);            // 此处使用让线程暂停0.5秒来模拟加载该组件            try            {                System.out.println("加载【" + position + "】位置的组件");                Thread.sleep(500);            }            catch (InterruptedException e)            {                e.printStackTrace();            }            return rv;        }        @Override        public RemoteViews getLoadingView()        {            return null;        }        @Override        public int getViewTypeCount()        {            return 1;        }        @Override        public long getItemId(int position)        {            return position;        }        @Override        public boolean hasStableIds()        {            return true;        }        @Override        public void onDataSetChanged()        {        }    }    }

widget_item.xml

<?xml version="1.0" encoding="utf-8"?><ImageView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/widget_item"    android:layout_width="120dp"    android:layout_height="120dp"    android:gravity="center"/>

StackWidgetProvider.java

package org.crazyit.desktop;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.widget.RemoteViews;import android.widget.Toast;/** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2014, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */public class StackWidgetProvider extends AppWidgetProvider{    public static final String TOAST_ACTION        = "org.crazyit.desktop.TOAST_ACTION";    public static final String EXTRA_ITEM         = "org.crazyit.desktop.EXTRA_ITEM";    @Override    public void onUpdate(Context context,        AppWidgetManager appWidgetManager, int[] appWidgetIds)    {        // 创建RemoteViews对象,加载/res/layout目录下的widget_layout.xml文件        RemoteViews rv = new RemoteViews(context.getPackageName(),            R.layout.widget_layout);        Intent intent = new Intent(context, StackWidgetService.class);        // 使用intent更新rv中stack_view组件(StackView)        rv.setRemoteAdapter(R.id.stack_view, intent);  //// 设置当StackWidgetService提供的列表项为空时,直接显示empty_view组件        rv.setEmptyView(R.id.stack_view, R.id.empty_view);        // 创建启动StackWidgetProvider组件(作为BroadcastReceiver)的Intent        Intent toastIntent = new Intent(context,            StackWidgetProvider.class);        // 为该Intent设置Action属性        toastIntent.setAction(StackWidgetProvider.TOAST_ACTION);        // 将Intent包装成PendingIntent        PendingIntent toastPendingIntent = PendingIntent            .getBroadcast(context, 0, toastIntent,                PendingIntent.FLAG_UPDATE_CURRENT);        // 将PendingIntent与stack_view进行关联        rv.setPendingIntentTemplate(R.id.stack_view,            toastPendingIntent);        // 使用AppWidgetManager通过RemteViews更新AppWidgetProvider        appWidgetManager.updateAppWidget(            new ComponentName(context, StackWidgetProvider.class), rv); //        super.onUpdate(context, appWidgetManager, appWidgetIds);    }    @Override    public void onDeleted(Context context, int[] appWidgetIds)    {        super.onDeleted(context, appWidgetIds);    }    @Override    public void onDisabled(Context context)    {        super.onDisabled(context);    }    @Override    public void onEnabled(Context context)    {        super.onEnabled(context);    }    // 重写该方法,将该组件当成BroadcastReceiver使用    @Override    public void onReceive(Context context, Intent intent)    {        if (intent.getAction().equals(TOAST_ACTION))        {            // 获取Intent中的数据            int viewIndex = intent.getIntExtra(EXTRA_ITEM, 0);            // 显示Toast提示            Toast.makeText(context, "点击第【" + viewIndex + "】个列表项",                Toast.LENGTH_SHORT).show();        }        super.onReceive(context, intent);    }    }

widget_layout.xml

<?xml version="1.0" encoding="utf-8"?><FrameLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:layout_margin="8dp">    <StackView        android:id="@+id/stack_view"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:loopViews="true" />    <TextView        android:id="@+id/empty_view"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:background="#ff0f"        android:textColor="#ffffff"        android:textStyle="bold"        android:text="@string/no_item"        android:textSize="20sp" /></FrameLayout>

Manifest.xml

<?xml version="1.0" encoding="utf-8" ?><manifest    xmlns:android="http://schemas.android.com/apk/res/android"    package="org.crazyit.desktop"    android:versionCode="1"    android:versionName="1.0">    <uses-sdk        android:minSdkVersion="14"        android:targetSdkVersion="17" /><application    android:allowBackup="true"    android:label="@string/app_name">    <!-- 配置AppWidgetProvider,即配置桌面控件 -->    <receiver android:name=".StackWidgetProvider">        <!-- 通过该intent-filter指定该Receiver作为桌面控件 -->        <intent-filter>            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />        </intent-filter>        <!-- 为桌面控件指定meta-data -->        <meta-data            android:name="android.appwidget.provider"            android:resource="@xml/stackwidgetinfo" />    </receiver>    <!-- 配置RemoteViewsService    必须指定权限为android.permission.BIND_REMOTEVIEWS     -->    <service        android:name=".StackWidgetService"        android:permission="android.permission.BIND_REMOTEVIEWS"        android:exported="false" /></application></manifest>

stackwidgetinfo.xml

<?xml version="1.0" encoding="utf-8"?><appwidget-provider    xmlns:android="http://schemas.android.com/apk/res/android"    android:minWidth="110dp"    android:minHeight="110dp"    android:updatePeriodMillis="3600000"    android:previewImage="@drawable/ic_launcher"    android:initialLayout="@layout/widget_layout"    android:resizeMode="horizontal|vertical"    android:autoAdvanceViewId="@id/stack_view"></appwidget-provider>

截图:

更多相关文章

  1. Activity类的runOnUiThread方法
  2. android使用html标签
  3. Android(安卓)WebView开发全攻略
  4. 我的javaSE学习笔记
  5. android之数据库和Content Provider(二)
  6. android 面试经典(4)
  7. Flutter 基础组件之 Stack
  8. Android进程间通讯——AIDL
  9. android Camera api1和api2学习笔记

随机推荐

  1. Android的SwitchCompat和Switch
  2. Android Studio App LinearLayout多层布
  3. android细节知识小点(动态更新)
  4. android 获取网络上服务器图片
  5. android中IO操作数据总结
  6. Android在自己的程序中调用外部程序
  7. android 记得用mkdirs不要用mkdir
  8. android 拖拽图片&拖动浮动按钮到处跑
  9. Android -- EditText插入表情
  10. CheckBox自定义样式