android AppWidget 支持ListView

android API 11 RemoteViews 提供出一些新的方法,让我们可以在桌面widget上添加一些复杂界面元素。

比较有代表性的是 ListView。就此写贴做个记录与分享。

 

源码

http://download.csdn.net/detail/yarkey09/6513753

 

效果图

android AppWidget 支持ListView_第1张图片

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yarkey.remoteviewstest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.yarkey.remoteviewstest.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name="MyWidget" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget" />
        </receiver>

        <service
            android:name="MyWidgetService"
            android:exported="false"
            android:permission="android.permission.BIND_REMOTEVIEWS" >
        </service>
    </application>

</manifest>

请注意加入权限:android:permission="android.permission.BIND_REMOTEVIEWS

否则我们定义的Service不会onBind,待会Factory的代码就不会被调用。

 

AppWidgetProvider.java

package com.yarkey.remoteviewstest;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.widget.RemoteViews;


public class MyWidget extends AppWidgetProvider {

	private static final String TAG = "MyWidget";

	/** package */
	static ComponentName getComponentName(Context context) {
		return new ComponentName(context, MyWidget.class);
	}

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
		Log.d(TAG, "onUpdate");
		performUpdate(context, appWidgetManager, appWidgetIds, null);
	}

	private void performUpdate(Context context, AppWidgetManager awm, int[] appWidgetIds, long[] changedEvents) {
		for (int appWidgetId : appWidgetIds) {
			Log.d(TAG, "appWidgetId = " + appWidgetId);
			Intent intent = new Intent(context, MyWidgetService.class);
			intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
			intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));

			RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.layout_widget);
			views.setTextViewText(R.id.button1, "已更新");
			views.setRemoteAdapter(R.id.listView1, intent);

			awm.updateAppWidget(appWidgetId, views);
			awm.notifyAppWidgetViewDataChanged(appWidgetId, R.id.listView1);
		}
	}
}

关键就是:views.setRemoteAdapter( int viewId, Intent intent )

这个方法在API 14才有。API 11相同方法 setRemoteAdapter( int appWidgetId, int viewId, Intent intent )

 

RemoteViewsService.java

package com.yarkey.remoteviewstest;

import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;

public class MyWidgetService extends RemoteViewsService {

	private static final boolean DB = true;
	private static final String TAG = "MyWidgetService";

	@Override
	public RemoteViewsFactory onGetViewFactory(Intent intent) {
		log("onGetViewFactory, intent=" + intent);
		return new MyWidgetFactory(getApplicationContext(), intent);
	}

	public static class MyWidgetFactory implements RemoteViewsService.RemoteViewsFactory {

		private Context mContext;

		private String[] mFoods = new String[] { "Apple", "Banana", "Pear", "Handset", "People", "Bar", "Wind", "Song",
				"Source code", "Screen", "Package", "Cup", "Computer" };

		// 构造
		public MyWidgetFactory(Context context, Intent intent) {
			log("MyWidgetFactory");
			mContext = context;
		}

		@Override
		public int getCount() {
			log("getCount");
			return mFoods.length;
		}

		@Override
		public long getItemId(int position) {
			log("getItemId");
			return position;
		}

		// 在调用getViewAt的过程中,显示一个LoadingView。
		// 如果return null,那么将会有一个默认的loadingView
		@Override
		public RemoteViews getLoadingView() {
			log("getLoadingView");
			return null;
		}

		@Override
		public RemoteViews getViewAt(int position) {
			log("getViewAt, position=" + position);
			if (position < 0 || position >= getCount()) {
				return null;
			}
			RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.layout_item);
			views.setTextViewText(R.id.textView1, mFoods[position]);
			return views;
		}

		@Override
		public int getViewTypeCount() {
			log("getViewTypeCount");
			return 1;
		}

		@Override
		public boolean hasStableIds() {
			log("hasStableIds");
			return true;
		}

		@Override
		public void onCreate() {
			log("onCreate");
		}

		@Override
		public void onDataSetChanged() {
			log("onDataSetChanged");
		}

		@Override
		public void onDestroy() {
			log("onDestroy");
		}
	}

	private static void log(String log) {
		if (DB)
			Log.d(TAG, log);
	}
}

有点类似BaseAdapter, getCount(), getViewAt()

 

-- end --

你可能感兴趣的:(源码,android,ListView,RemoteViews,widget)