一,描述
在很多情况下,我们都需要自己的APP具有像,天气预报,微博,或者播放器这样的。在主屏幕里嵌入自己的窗口小部件的需求。
下面就是俺研究部件时的一个写的一个小DEMO。
二,开发准备
1,在res/目录下创建 XML 文件夹 下建立一个 appwidget-provider.xml 文件。
2,在res/layout/目录下建立一个widget.xml
三,配置文件和代码解释
1,appwidget-provider.xml:
<?xml version="1.0" encoding="UTF-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="60dp" android:minHeight="30dp" android:updatePeriodMillis="86400000" android:initialLayout="@layout/widget"> </appwidget-provider> <!--这里就是定义 窗口部件的宽,高,和指定布局文件 等待属性的。(详细的属性设置百度一大把) -->
2,widget.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="150dp" android:layout_height="120dp" android:orientation="vertical"> <Button android:id="@+id/btn_prve_widget" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="上一条" /> <TextView android:id="@+id/textview_info_widget" android:layout_width="fill_parent" android:layout_height="30dp" android:text="笑话载入中..." android:gravity="center" /> <Button android:id="@+id/btn_next_widget" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="下一条" /> </LinearLayout> <!--这里就是定义 窗口部件的界面布局文件(具体应用具体布局) -->
3,AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yeqw.android" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="7" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name="com.yeqw.android.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> <!--窗口部件配置begin--> <receiver android:name="com.yeqw.android.sample.AppWidgetProviderSample"> <meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_provider"></meta-data> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="PREV"></action> <action android:name="NEXT"></action> </intent-filter> </receiver> <!--窗口部件配置end--> </application> </manifest>
以下两个action 是具体应用具体定义了。主要就是做一些Action的判断。
<action android:name="PREV"></action> <action android:name="NEXT"></action>
4,部件Widget 实现的 java代码
package com.yeqw.android.sample; import com.yeqw.android.R; 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.widget.RemoteViews; public class AppWidgetProviderSample extends AppWidgetProvider{ //这个是部件传递数据和操作部件里的控件的一个通道(个人理解) private static RemoteViews rv; //部件更新的时候触发 @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // TODO Auto-generated method stub for (int i = 0; i < appWidgetIds.length; i++) { int appWidgetId = appWidgetIds[i]; updateAppWidget(context, appWidgetManager, appWidgetId); } } //布局被通知的时候触发 @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub super.onReceive(context, intent); String info="无数据"; if (rv == null) { return; } //通过Action 来判断是否是自己需要触发业务的Action,(这里Action 值必须和AndroidManifest.xml保持一致) if (intent.getAction().equals("PREV")) { info="获得上一条新数据了"; rv.setTextViewText(R.id.textview_info_widget, info); } else if (intent.getAction().equals("NEXT")) { info="获得下一条新数据了"; rv.setTextViewText(R.id.textview_info_widget, info); } AppWidgetManager appWidgetManger = AppWidgetManager.getInstance(context); int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName(context, AppWidgetProviderSample.class)); //更新部件 appWidgetManger.updateAppWidget(appIds, rv); } public static void updateAppWidget(Context context, AppWidgetManager appWidgeManger, int appWidgetId) { if(rv!=null)return; //这里就是初始化 部件里的各个控件。包括事件绑定。 rv = new RemoteViews(context.getPackageName(), R.layout.widget); String info="获得新数据了"; rv.setTextViewText(R.id.textview_info_widget, info); Intent prevIntent = new Intent("PREV"); PendingIntent prevPendingIntent = PendingIntent.getBroadcast(context,0,prevIntent,0); rv.setOnClickPendingIntent(R.id.btn_prve_widget,prevPendingIntent); Intent nextIntent = new Intent("NEXT"); PendingIntent nextPendingIntent = PendingIntent.getBroadcast(context,0,nextIntent,0); rv.setOnClickPendingIntent(R.id.btn_next_widget, nextPendingIntent); appWidgeManger.updateAppWidget(appWidgetId, rv); } }
四,总结
这个DEMO 里只用到了 onUpdate onReceive 事件(AppWidgetProvider 其他事件有想了解的百度一大把。)
主要 PendingIntent 用这个做按钮事件绑定的处理 和RemoteViews 这个部件里用的最多的一个类的操作。
还是那句话 具体应用具体对待,但路就是这样走的。根据业务我们可以从 数据的获取到 事件的处理都可以多样化的。
(俺属于实用主义者,但任何技术在运用到实际开发中一定要 知其然,更要知其所以然。)Demo只是一个方向一条路
但业务是千变万化的。所以还是那句 具体应用具体对待。呵呵(这个是过完年的第一篇blog 有点啰嗦。)