Android開發Widget之入門篇

一. Widget介紹: 

       Widget是窗口小部件的意思,比如時間Widget,日曆Widget等,可以顯示一些信息,或者點擊進入一個程序。比如下圖的時間Widget:

      

     下面帶大家做一個很簡單的Widget,點擊一個按鈕讓按鈕的文字發生變化,瞭解下流程。

二.Widget案例演示:

    1.我們先建一個widget_layout.xml文件作爲widget的佈局,就是桌面上顯示的佈局。在這裏只顯示一個按鈕。 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/btnSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="點擊" >
    </Button>

</RelativeLayout>

    2.我們在res目錄下新建一個xml目錄,在裏面新建一個 widget_config.xml文件,這個文件顧名思義是widget的配置文件,詳細的看代碼註釋。

    

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
   
    android:minHeight="40dp"
    android:minWidth="180dp"
    android:previewImage="@drawable/ic_launcher"
    android:updatePeriodMillis="1000"
    android:initialLayout="@layout/widget_layout"
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen|keyguard" >

    <!--
        計算寬高尺寸的公式: (70*n)-30  n爲部件所需的大小(佔幾格)   當前的就是  3X1  
        minWidth            widget的最小寬度
        minHeight           widget的最小高度
        previewImage        選擇部件時 展示的圖標    
        updatePeriodMillis  更新時間間隔  
        initialLayout       佈局文件  
        resizeMode          表示支持的模式,這裏支持水平和垂直    
        widgetCategory="keyguard|home_screen"   表示widget可添加的位置 鎖屏界面|桌面  
    -->

</appwidget-provider>
   3.開始編寫代碼。我們新建一個 ClickAppWidget繼承自 AppWidgetProvider,如果你看 AppWidgetProvider的源碼會發現它繼承自BroadcastReceiver。

public class AppWidgetProvider extends BroadcastReceiver {
    /**
     * Constructor to initialize AppWidgetProvider.
     */
    public AppWidgetProvider() {
    }
   。。。。。。

     我們重寫它的onDeleted,onDisabled,onEnabled,onUpdate和onReceive方法。在什麼時候調用這些方法代碼裏都標明瞭,這裏只重點說下onReceive和onUpdate方法。

   onReceive方法接受廣播事件,可以在這裏更新RemoteViews,從而更新widget。先獲取RemoteViews實例, new RemoteViews()接受兩個參數,一個是應用包名,一個是widget的佈局文件。然後通過setTextViewText(R.id.btnSend, "點擊成功")設置按鈕的值,第一個參數是控件的id,第二個參數是設置內容。如果你的佈局有ImageView,你可以調用setImageViewResource(viewId, srcId)設置圖片。之後通過獲取widget的管理者AppWidgetManager,可以看到這裏是單例模式,再通過AppWidgetManager實例獲取該應用的所有appWidgetIds,以數組形式返回,最終調用updateAppWidget方法,傳入appWidgetIds和remoteViews兩個參數就可以了。

  onUpdate方法是在到達xml配置文件裏 指定的更新時間或者當用戶向桌面添加Widget時就被調用,所以它比onReceive方法先執行,這裏我們構建了一個Intent對象,設置一個action爲click,然後構建一個創建廣播的PendingIntent對象,獲得RemoteViews實例,調用setOnClickPendingIntent方法即可,當點擊這個按鈕時就會發送廣播。

   具體的代碼就貼在下面:

     

public class ClickAppWidget extends AppWidgetProvider {
	private static final String TAG = "ClickAppWidget";
	
	// 刪除widget的時候調用
	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		Log.i(TAG, "onDeleted");
		super.onDeleted(context, appWidgetIds);
	}

	// 當最後一個widget被刪除時調用
	@Override
	public void onDisabled(Context context) {
		Log.i(TAG, "onDisabled");
		super.onDisabled(context);
	}

	// widget第一次被添加到桌面的時候調用
	@Override
	public void onEnabled(Context context) {
		Log.i(TAG, "onEnabled");
		super.onEnabled(context);
	}

	// 接受廣播事件,接受一次就調用一次,和普通廣播用法一樣
	@Override
	public void onReceive(Context context, Intent intent) {

		if (intent.getAction().equals("click")) {
			Log.i(TAG, "onReceive");

		    // 獲得該widget的遠程視圖實例
			RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_layout);
			
			remoteViews.setTextViewText(R.id.btnSend, "點擊成功");
			   
			AppWidgetManager mWidgetManager = AppWidgetManager.getInstance(context);
			//獲得該應用的所有appWidgetIds
			int[] appWidgetIds = mWidgetManager.getAppWidgetIds(new ComponentName(context,ClickAppWidget.class));
			mWidgetManager.updateAppWidget(appWidgetIds, remoteViews);

		}

		super.onReceive(context, intent);
	}
 	/**
	 * 到達xml配置文件裏 指定的更新時間或者當用戶向桌面添加Widget時就被調用
	 * @param AppWidgetManager  AppWidget的管理器          
	 * @param appWidgetIds      桌面上 所有的widget都會被分配一個唯一的ID,存在數組裏           
	 * */
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		// 創建一個Intent,設定action爲click
		Intent intent  = new Intent("click");

		// 設置pendingIntent的作用
		PendingIntent mpendingIntent = PendingIntent.getBroadcast(context, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);

		//  獲得該widget的遠程視圖實例
		RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_layout);
		
		//  設定點擊事件
		remoteViews.setOnClickPendingIntent(R.id.btnSend, mpendingIntent);

		//  調用updateAppWidget方法更新Appwidget
		appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
                 
	}
}
   4.最後要在Manifest裏添加如下代碼   

 <receiver android:name="ClickAppWidget" >
            <intent-filter>
                <action android:name="click" >
                </action>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" >
                </action>
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_config" />
        </receiver>
   

       action裏的值android.appwidget.action.APPWIDGET_UPDATE是默認的,meta-data裏的name也是默認值,resource的引用的是之前新建的widget配置文件。

 三.結果展示

       我們運行應用後,點添加小工具就可以把widget放到桌面上。

        點擊之前和點擊之後,widget發生了變化

                 

     

   

     附上Demo下載地址:點擊打開鏈接

      

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章