Android的桌面小圖示Widget的學習
阿新 • • 發佈:2018-12-24
android提供向桌面上放置一個遠端佈局的功能。最近學了一下,在這裡記錄一下學習筆記。
public class MyWidget extends AppWidgetProvider{ public static String TAG = "MyWidget"; @Override public void onReceive(Context context, Intent intent) { Log.i(TAG, "onReceive: "); super.onReceive(context, intent); } @Override public void onEnabled(Context context) { Log.i(TAG, "onEnabled: "); super.onEnabled(context); } @Override public void onDeleted(Context context, int[] appWidgetIds) { Log.i(TAG, "onDeleted: "); super.onDeleted(context, appWidgetIds); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { Log.i(TAG, "onUpdate: "); super.onUpdate(context, appWidgetManager, appWidgetIds); } @Override public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) { Log.i(TAG, "onRestored: "); super.onRestored(context, oldWidgetIds, newWidgetIds); } @Override public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { Log.i(TAG, "onAppWidgetOptionsChanged: "); super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); } @Override public void onDisabled(Context context) { Log.i(TAG, "onDisabled: "); super.onDisabled(context); } }
1,首先要建一個類MyWidget繼承AppWidgetProvider,通過檢視他的原始碼可以知道它是一個BroadcastReceiver。所以要在清單檔案當中註冊。
它的action為:android.appwidget.action.APPWIDGET_UPDATE。
<receiver android:name=".MyWidget" android:icon="@mipmap/desk_play" android:label="音樂"> <intent-filter> <actionandroid:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_info" /> </receiver>
<meta-data>元素中定義了Widget的AppWidgetInfo的資訊。appwidget_info.xml檔案在res/xml資料夾下。內容是:
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="40dp" android:minHeight="40dp" android:updatePeriodMillis="86400000" android:previewImage="@drawable/play_ic" android:initialLayout="@layout/my_widget" android:resizeMode="horizontal|vertical" android:widgetCategory="home_screen|keyguard"> </appwidget-provider> <!-- <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="40dp" android:minHeight="40dp" android:updatePeriodMillis="86400000" android:previewImage="@drawable/preview" android:initialLayout="@layout/example_appwidget" android:configure="com.example.android.ExampleAppWidgetConfigure" android:resizeMode="horizontal|vertical" android:widgetCategory="home_screen|keyguard" android:initialKeyguardLayout="@layout/example_keyguard"> </appwidget-provider> minWidth和minHeight是widget在桌面上的的最小的寬高 updatePeriodMillis是Widget的重新整理時間,單位是:ms。如果要是需要頻繁的更新。可以用AlarmManager,並且設定Type為ELAPSED_REALTIME或者RTC。 initialLayout是一個佈局就是Widget的佈局。 configure的是一個Activity。當向桌面上新增Widget的時候就會啟動,用來提示這個Widget的作用 previewImage是當選擇該Widget新增到桌面的時候的的顯示圖片。拖動widget向桌面的圖片 resizeMode是widget在桌面上調整大小的時候的模式,水平方向,垂直方向。 widgetCategory是widget顯示的位置,桌面或鎖屏的介面 initialKeyguardLayout是鎖屏的時候的顯示佈局 -->然後就可以在佈局檔案當中設定widget的顯示佈局。在Widget的佈局要依賴RemoteViews ,RemoteViews對指定的控制元件進行支援
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/play_ic"> </LinearLayout> <!-- Widget的佈局中只支援一下的佈局和控制元件。不支援這些控制元件的子類是不支援的: FrameLayout LinearLayout RelativeLayout GridLayout AnalogClock Button Chronometer ImageButton ImageView ProgressBar TextView ViewFlipper ListView GridView StackView AdapterViewFlipper -->
做完這些就可以在桌面上新增Widget了。
2,Widget的生命週期。
第一次建立一個Widget: 04-03 10:26:13.416 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onReceive: 04-03 10:26:13.416 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onEnabled: 04-03 10:26:13.416 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onReceive: 04-03 10:26:13.420 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onUpdate: 第二次建立一個Widget: 04-03 10:26:39.515 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onReceive: 04-03 10:26:39.515 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onUpdate: 第三次建立一個Widget 04-03 10:29:07.485 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onReceive: 04-03 10:29:07.485 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onUpdate: 修改Widget在桌面上的大小的時候 04-03 10:30:09.057 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onReceive: 04-03 10:30:09.057 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onAppWidgetOptionsChanged: 移除一個Widget 04-03 10:30:34.692 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onReceive: 04-03 10:30:34.692 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onDeleted: 再移除一個: 04-03 10:30:34.692 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onReceive: 04-03 10:30:34.692 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onDeleted: 當最後一個被移除的時候: 04-03 10:31:44.211 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onReceive: 04-03 10:31:44.211 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onDeleted: 04-03 10:31:44.219 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onReceive: 04-03 10:31:44.219 1300-1300/com.example.yyw.appwidgetdemo I/MyWidget: onDisabled:從上面的log可以看出:
onReceive在每一次的建立和移除都會呼叫。
onEnabled只有在第一的時候才會呼叫。
onUpdate在每次建立都會呼叫的。而且在android:updatePeriodMillis的時間到的時候也會呼叫。
onDeleted在每次移除一個Widget的時候會被呼叫。
onDisabled在全部移除Widget的時候會呼叫到。
onAppWidgetOptionsChanged會在改變Widget大小的時候呼叫。
3,新增桌面view的點選事件。
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int id : appWidgetIds ) {
Log.i(TAG, "onUpdate: " + id);
AppWidgetManager am = AppWidgetManager.getInstance(context);
//Widget是在其他應用上面顯示的所以要用RemoteViews來管理
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.my_widget);
Intent intent = new Intent(context,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context,2016,intent,0);
//設定點選圖片的點選事件,開啟一個Activity
remoteViews.setOnClickPendingIntent(R.id.iv,pendingIntent);
//把Widget更新
am.updateAppWidget(id,remoteViews);
}
//
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
用PendingIntent做為管理點選事件的的處理事件,可以開啟Activity,service,broadcast。