給你的app添加桌面widget

首先,什麼是桌面widget,桌面widget是一種桌面插件,以下圖: android

 

這種類型的控件叫作widget,通常長按桌面會彈出一個界面讓你選擇控件,選擇完了拖到桌面就能使用了。git

下面咱們爲這個app來添加一個widget,先看一下效果吧。 github

 

 

而後點擊這個桌面widget,讓他跳轉到咱們的app裏面app

 

怎麼樣,效果還不錯吧?ide

下面重點講一下實現widget的主要步驟: 
1. 在AndroidManifest.xml裏面定義聲明 AppWidgetProvider 
2. 初始化AppWidget的xml文件(信息) 
3. 實現AppWidget的佈局 
4. 繼承 AppWidgetProvider 類,實現具體的 Widget 業務邏輯。

 

一、在AndroidManifest.xml裏面定義聲明 AppWidgetProvider函數

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

<intent-filter>中必需要包含 APPWIDGET_UPDATE 這個 <action>,全部 Widget 的 broadcast 都是經過這個 filter 來接收的。<meta-data> 聲明瞭 Widget的xml 信息,用的是 xml 目錄下的 widget_info.xml。佈局

 

二、widget_info.xmlspa

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="250dp"
    android:minHeight="170dp"
    android:updatePeriodMillis="0"
    android:previewImage="@drawable/widget_preview"
    android:initialLayout="@layout/widget_layout"
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="keyguard|home_screen">
</appwidget-provider>

記住,這個文件不是widget的佈局,而是widget的信息,描述了widget的寬高、刷新時間等等信息。 
minWidth & minHeight:定義了 Widget 的最小寬高,當 minWidth 和 minHeight 不是桌面 cell 的整數倍時,Widget 的寬高會被闊至與其最接近的 cells 大小。Google 官方給出了一個大體估算 minWidth & minHeight 的公式,根據 Widget 所佔的 cell 數量來計算寬高:70 × n − 30,n 是所佔的 cell 數量。.net

updatePeriodMillis: 定義了 Widget 的刷新頻率,也就是 App Widget Framework 多久請求一次 AppWidgetProvider 的 onUpdate() 回調函數。可是,系統默認最小更新時間是30分鐘,若是這裏定義的時間小於30分鐘,那麼刷新時間仍是30分鐘。插件

previewImage:widget的預覽圖,就是咱們widget列表裏面那些預覽圖

initialLayout: 這裏定義的纔是widget的佈局

resizeMode:Widget 在水平和垂直方向是否能夠調整大小,值能夠爲:horizontal(水平方向能夠調整大小),vertical(垂直方向能夠調整大小),none(不能夠調整大小),也能夠 horizontal|vertical 組合表示水平和垂直方向都可以調整大小。

widgetCategory:表示 Widget 能夠顯示的位置,包括 home_screen(桌面),keyboard(鎖屏),keyboard 屬性須要 5.0 或以上 Android 版本才能夠。

 

三、AppWidget的佈局 
這裏佈局能夠隨便寫,我簡單的寫了個ImageView

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/iv_widget"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/widget_preview"
        android:layout_centerHorizontal="true"/>
</RelativeLayout>

 

四、繼承 AppWidgetProvider 

public class RecyclerWidgetProvider extends AppWidgetProvider {
    public RecyclerWidgetProvider() {
        super();
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        Log.i("shenlong", "onUpdate");
        for (int i = 0; i < appWidgetIds.length; i++) {
            int appWidgetId = appWidgetIds[i];
            Log.i("shenlong", "onUpdate appWidgetId=" + appWidgetId);
            Intent intent = new Intent();
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |
                    Intent.FLAG_ACTIVITY_TASK_ON_HOME);
            intent.setClass(context, MainActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

            // Get the layout for the App Widget and attach an on-click listener
            // to the button
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
            views.setOnClickPendingIntent(R.id.iv_widget, pendingIntent);

            // Tell the AppWidgetManager to perform an update on the current app widget
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }


    /**
     * 當 Widget 被刪除時調用該方法。
     *
     * @param context
     * @param appWidgetIds
     */
    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        super.onDeleted(context, appWidgetIds);
        Toast.makeText(context, "onDeleted", Toast.LENGTH_SHORT).show();
    }

    /**
     * 當 Widget 第一次被添加時調用,例如用戶添加了兩個你的 Widget,那麼只有在添加第一個 Widget 時該方法會被調用。
     * 因此該方法比較適合執行你全部 Widgets 只需進行一次的操做
     *
     * @param context
     */
    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
    }

    /**
     * 與 onEnabled 剛好相反,當你的最後一個 Widget 被刪除時調用該方法,因此這裏用來清理以前在 onEnabled() 中進行的操做。
     *
     * @param context
     */
    @Override
    public void onDisabled(Context context) {
        super.onDisabled(context);
    }

    /**
     * 當 Widget 第一次被添加或者大小發生變化時調用該方法,能夠在此控制 Widget 元素的顯示和隱藏。
     *
     * @param context
     * @param appWidgetManager
     * @param appWidgetId
     * @param newOptions
     */
    @Override
    public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
        super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
    }

    @Override
    public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
        super.onRestored(context, oldWidgetIds, newWidgetIds);
    }
}

註釋寫的應該還蠻詳細的, 
onUpdateonDeletedonDisabledonAppWidgetOptionsChanged等函數的調用時機都寫在註釋裏了。另外,AppWidgetProvider 繼承自 BroadcastReceiver,因此要實現onReceive()方法, onReceive() 中處理的是 Widget 相關的廣播事件,而後分發到各個回調函數中onUpdate()onDeleted()onEnabled()onDisabledonAppWidgetOptionsChanged()

 

五、爲widget添加點擊事件

a、首先先定義個開啓Activity的intent

Intent intent = new Intent();

 

b、用intent實例化一個PendingIntent,調用pendingIntent的getActicity方法來啓動另外一個Activity

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

 

c、實例化RemoteView,其對應相應的Widget佈局

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);

 

d、給RemoteView上的控件設置按鈕事件

views.setOnClickPendingIntent(R.id.iv_widget, pendingIntent);

 

e、更新AppWidget界面

appWidgetManager.updateAppWidget(appWidgetId, views);

 

這樣,就實現了點擊事件,效果圖能夠見上圖

源碼:https://github.com/AdleyLong/RecyclerViewDemo

 

轉: https://blog.csdn.net/Picasso_L/article/details/70597609

相關文章
相關標籤/搜索