zoukankan      html  css  js  c++  java
  • Android 4.0 新增的显示数据集的桌面控件

    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>

    截图:

    image

  • 相关阅读:
    Jquery 图片预览插件 imgPreview
    对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)
    JavaScript拖拽实现(附注释),最经典!最简单!短小精悍!
    如何使用VC++写一个小程序来检测.NetFrameWork版本
    利用TreeView实现C#工具箱效果
    JavaScript中json对象和string对象之间的转化
    Ubuntu Server上搭建可用于生产环境的ASP.NET服务器
    winexec()函数的参数说明(c++)
    C#对文件夹的判断、创建、移动、删除
    C#程序不用安装.NET环境运行(让C#程序脱离.net框架)
  • 原文地址:https://www.cnblogs.com/AndyGe/p/3442833.html
Copyright © 2011-2022 走看看