Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Widget 小部件(四---完結) 使用ListView、GridView、StackView、ViewFlipper展示Widget

Android Widget 小部件(四---完結) 使用ListView、GridView、StackView、ViewFlipper展示Widget

編輯:關於Android編程

官方有話這樣說:

A RemoteViews object (and, consequently, an App Widget) can support the following layout classes:

  • FrameLayout
  • LinearLayout
  • RelativeLayout

    And the following widget classes:

    • AnalogClock
    • Button
    • Chronometer
    • ImageButton
    • ImageView
    • ProgressBar
    • TextView
    • ViewFlipper
    • ListView
    • GridView
    • StackView
    • AdapterViewFlipper

      Descendants of these classes are not supported.不支持這些類的後代

      接下來的示例說明怎麼樣實現 使用ListView、GridView、StackView、ViewFlipper創建AppWidget

      menifest

      
                   
                       
                       
                       
                   
                   
      

      set_widget_provider.xml

      
      
      	
      
      

      widget使用的布局文件 collections_view_widget.xml

      
      
      
          
      
              

      集合的數據源 需要 繼承 RemoteViewsService

      package com.stone.service;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import android.app.PendingIntent;
      import android.content.Context;
      import android.content.Intent;
      import android.os.Bundle;
      import android.widget.RemoteViews;
      import android.widget.RemoteViewsService;
      
      import com.stone.R;
      import com.stone.receiver.WidgetSetProvider;
      
      /**
       * 繼承自RemoteViewsService 必須重寫onGetViewFactory
       * 該服務只是用來 創建 集合widget使用的數據源
       * @author stone
       */
      public class WidgetSetService extends RemoteViewsService {
      	
      	public WidgetSetService() {
      		
      	}
      	
      	@Override
      	public RemoteViewsFactory onGetViewFactory(Intent intent) {
      		return new WidgetFactory(this.getApplicationContext(), intent);
      	}
      	
      	
      	public class WidgetFactory implements RemoteViewsService.RemoteViewsFactory {
      		private static final int mCount = 10;
      		private Context mContext;
      		private List mWidgetItems = new ArrayList();
      		
      		
      		public WidgetFactory(Context context, Intent intent) {
      	        mContext = context;
      //	        mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
      //	                AppWidgetManager.INVALID_APPWIDGET_ID);
      	    }
      		
      		@Override
      		public void onCreate() {
      			for (int i = 0; i < mCount; i++) {
                      mWidgetItems.add("item:" + i + "!");
                  }
      		}
      
      		@Override
      		public void onDataSetChanged() {
      			/*
      			 * appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.listview);
      			 * 使用該通知更新數據源,會調用onDataSetChanged
      			 */
      			System.out.println("----onDataSetChanged----");
      		}
      
      		@Override
      		public void onDestroy() {
      			mWidgetItems.clear();
      		}
      
      		@Override
      		public int getCount() {
      			return  mCount;
      		}
      
      		@Override
      		public RemoteViews getViewAt(int position) {
      			RemoteViews views = new RemoteViews(mContext.getPackageName(), android.R.layout.simple_list_item_1);
      			views.setTextViewText(android.R.id.text1, "item:" + position);
      			System.out.println("RemoteViewsService----getViewAt" + position);
      			
      			
      			Bundle extras = new Bundle();
                  extras.putInt(WidgetSetProvider.EXTRA_ITEM, position);
                  Intent fillInIntent = new Intent();
                  fillInIntent.putExtras(extras);
                  /*
                   * android.R.layout.simple_list_item_1 --- id --- text1
                   * listview的item click:將fillInIntent發送,
                   * fillInIntent它默認的就有action 是provider中使用 setPendingIntentTemplate 設置的action
                   */
      			views.setOnClickFillInIntent(android.R.id.text1, fillInIntent);
      			
      			return views;
      		}
      
      		@Override
      		public RemoteViews getLoadingView() {
      			/* 在更新界面的時候如果耗時就會顯示 正在加載... 的默認字樣,但是你可以更改這個界面
      			 * 如果返回null 顯示默認界面
      			 * 否則 加載自定義的,返回RemoteViews
      			 */
      			return null;
      		}
      
      		@Override
      		public int getViewTypeCount() {
      			return 1;
      		}
      
      		@Override
      		public long getItemId(int position) {
      			return position;
      		}
      
      		@Override
      		public boolean hasStableIds() {
      			return false;
      		}
      		
      	}
      
      }
      

      widgetprovider

      package com.stone.receiver;
      
      import com.stone.R;
      import com.stone.service.WidgetSetService;
      
      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.os.Bundle;
      import android.text.TextUtils;
      import android.text.format.DateUtils;
      import android.view.View;
      import android.widget.RemoteViews;
      import android.widget.Toast;
      import android.widget.ViewFlipper;
      
      /**
       * 使用了集合展示AppWidget
       * ListView、GridView、StackView 設置adapter,處理item點擊
       * ViewFlipper 在RemoteViews中缺少支持,暫只能在它的布局文件中設置 輪換效果
       * 				對於切換到哪一個子view的item事件不好處理,只能設置一個整體setPendingIntent
       * @author stone
       */
      public class WidgetSetProvider extends AppWidgetProvider {
      	public final static String CLICK_ACTION = "com.stone.action.clickset";
      	public final static String CLICK_ITEM_ACTION = "com.stone.action.clickset.item";
      	public final static String EXTRA_ITEM = "extra_item";
      	
      	@Override
      	public void onReceive(Context context, Intent intent) {
      		super.onReceive(context, intent);
      		System.out.println(intent.getAction());
      		if (TextUtils.equals(CLICK_ACTION, intent.getAction())) {
      			int extraType = intent.getIntExtra("view_tag", 0);
      			if (extraType > 0) {
      				System.out.println("extra:::" + extraType);
      				
      				switch (extraType) {
      				case 1:
      					updateWidget(context, R.id.listview, R.id.gridview, R.id.stackview, R.id.viewflipper);
      					break;
      				case 2:
      					updateWidget(context, R.id.gridview, R.id.listview, R.id.stackview, R.id.viewflipper);
      					break;
      				case 3:
      					updateWidget(context, R.id.stackview, R.id.gridview, R.id.listview, R.id.viewflipper);
      					break;
      				case 4:
      					updateWidget(context, R.id.viewflipper, R.id.gridview, R.id.stackview, R.id.listview);
      					break;
      	
      				default:
      					break;
      				}
      			} 
      		} else if (TextUtils.equals(CLICK_ITEM_ACTION, intent.getAction())) {
      			Bundle extras = intent.getExtras();
      			int position = extras.getInt(WidgetSetProvider.EXTRA_ITEM, -1);
      			if (position != -1) {
      				System.out.println("--點擊了item---" + position);
      				System.out.println("");
      //				Toast.makeText(context, "click item:" + position, 0).show();
      			}
      		}
      	}
      
      	@Override
      	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
      		RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.collections_view_widget);
      		
      		Intent intent1 = new Intent(CLICK_ACTION);
      		intent1.putExtra("view_tag", 1);
      		PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 101, intent1, 0);
      		views.setOnClickPendingIntent(R.id.btn_listview, pendingIntent1);
      		
      		Intent intent2 = new Intent(CLICK_ACTION);
      		intent2.putExtra("view_tag", 2);
      		PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 102, intent2, 0);
      		views.setOnClickPendingIntent(R.id.btn_gridview, pendingIntent2);
      		
      		Intent intent3 = new Intent(CLICK_ACTION);
      		intent3.putExtra("view_tag", 3);
      		PendingIntent pendingIntent3 = PendingIntent.getBroadcast(context, 103, intent3, 0);
      		views.setOnClickPendingIntent(R.id.btn_stackview, pendingIntent3);
      		
      		Intent intent4 = new Intent(CLICK_ACTION);
      		intent4.putExtra("view_tag", 4);
      		PendingIntent pendingIntent4 = PendingIntent.getBroadcast(context, 104, intent4, 0);
      		views.setOnClickPendingIntent(R.id.btn_viewflipper, pendingIntent4);
      		
      		appWidgetManager.updateAppWidget(appWidgetIds, views);
      		
      		System.out.println("setwidget update");
      		super.onUpdate(context, appWidgetManager, appWidgetIds);
      	}
      
      	@Override
      	public void onAppWidgetOptionsChanged(Context context, 
      			AppWidgetManager appWidgetManager, int appWidgetId,
      			Bundle newOptions) {
      		super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId,
      				newOptions);
      	}
      
      	@Override
      	public void onDeleted(Context context, int[] appWidgetIds) {
      		super.onDeleted(context, appWidgetIds);
      	}
      
      	@Override
      	public void onEnabled(Context context) {
      		super.onEnabled(context);
      	}
      
      	@Override
      	public void onDisabled(Context context) {
      		super.onDisabled(context);
      	}
      	
      	private void updateWidget(Context context, int visible, int gone1, int gone2, int gone3) {
      		//RemoteViews處理異進程中的View
      		RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.collections_view_widget);
      		
      		views.setViewVisibility(visible, View.VISIBLE);
      		views.setViewVisibility(gone1, View.GONE);
      		views.setViewVisibility(gone2, View.GONE);
      		views.setViewVisibility(gone3, View.GONE);
      		
      		if (visible != R.id.viewflipper) {//viewflipper 不是 繼承自AbsListView  or  AdapterViewAnimator  的view
      			Intent intent = new Intent(context, WidgetSetService.class);
      			views.setRemoteAdapter(visible, intent);//設置集合的adapter為intent指定的service
      			views.setEmptyView(visible, R.id.tv_empty);//指定集合view為空時顯示的view
      			
      			Intent toIntent = new Intent(CLICK_ITEM_ACTION);
      			PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 200, toIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      			/*
      			 * setPendingIntentTemplate 設置pendingIntent 模板
      			 * setOnClickFillInIntent   可以將fillInIntent 添加到pendingIntent中
      			 */
      			views.setPendingIntentTemplate(visible, pendingIntent);
      			
      		} else if (visible == R.id.viewflipper) {
      //			views.setPendingIntentTemplate(R.id.viewflipper, pendingIntentTemplate);
      		}
      		
      		AppWidgetManager am = AppWidgetManager.getInstance(context);
      		int[] appWidgetIds = am.getAppWidgetIds(new ComponentName(context, WidgetSetProvider.class));
      		for (int i = 0; i < appWidgetIds.length; i++) {
      			am.updateAppWidget(appWidgetIds[i], views); //更新 實例
      		}
      		
      	}
      	
      }
      

      運行的周期函數

      \

      點擊stackview的效果圖




  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved