Android 开发笔记五 AppWidget 的使用

AppWidget 就是可以放在桌面上的应用程序小组件. 可以在上面显示或操作一些常用的内容. 比传统的图标更加的丰富,绚丽,实用.

使用AppWidget 需要准备如下内容:

1. 一个 定义 这个 AppWidget 元数据的 XML 文档.

  我们可以在 res/ 下面创建一个 xml 文件夹. 在里面创建一个 如: myappwidget_info.xml.

  内容如下: 

1 <?xml version="1.0" encoding="utf-8"?>
2 <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
3     android:minHeight="72dp" 
4     android:minWidth="72dp" 
5     android:updatePeriodMillis="86400000" 
6     android:initialLayout="@layout/widgetprovider_layout"
7     >
8 </appwidget-provider>

  解释: minHeight,minWidth 就是这个Widget的Size的最小的值 Android推荐 (单元格数*74)-2,但我想只使用一行的时候,写 72 高,还会是两行.改成小点儿,我改成36 就是一行了~, ** 注意这个大小的值 如果设置得不合理的话,将不能正确的创建 Widget **

      android:updatePeriodMillis : 刷新周期(据说已经失效了,默认30分钟更新一下,不确定)

      android:initialLayout : 就这个Widget的布局文件.(这个布局文件,我们要在下面创建)

2. 创建Widget的Layout 布局文件,也就是告诉系统, 我们定义的Widget长的是什么样子的.

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6 
 7     <ImageView
 8         android:id="@+id/imageView1"
 9         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"
11         android:src="@drawable/ic_launcher" />
12 
13 <Button
14     android:id="@+id/button1"
15     android:layout_width="wrap_content"
16     android:layout_height="wrap_content"
17     android:layout_alignParentTop="true"
18     android:layout_toRightOf="@+id/imageView1"
19     android:text="Button" />
20 
21 </RelativeLayout>

  这里,我们使用线性布局,放上一个ImageView 和一个 Button

3. 创建一个 继承自 AppwidgetProvider 的类

 1 package ztc.appwidgettest;
 2 
 3 import android.app.PendingIntent;
 4 import android.appwidget.AppWidgetManager;
 5 import android.appwidget.AppWidgetProvider;
 6 import android.content.Context;
 7 import android.content.Intent;
 8 import android.widget.RemoteViews;
 9 
10 public class MyAppWidgetProvider extends AppWidgetProvider {
11     @Override
12     public void onDeleted(Context context, int[] appWidgetIds) {
13         // TODO Auto-generated method stub
14         super.onDeleted(context, appWidgetIds);
15     }
16 
17     @Override
18     public void onDisabled(Context context) {
19         // TODO Auto-generated method stub
20         super.onDisabled(context);
21     }
22 
23     @Override
24     public void onEnabled(Context context) {
25         // TODO Auto-generated method stub
26         super.onEnabled(context);
27     }
28 
29     @Override
30     public void onReceive(Context context, Intent intent) {
31         // TODO Auto-generated method stub
32         super.onReceive(context, intent);
33     }
34 
35     @Override
36     public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
37         // TODO Auto-generated method stub
38         super.onUpdate(context, appWidgetManager, appWidgetIds);
39 
40         // 创建Intent
41         Intent intent = new Intent();
42         intent.setClass(context, MainActivity.class);
43         // 创建 PendingIntent
44         PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);
45         // 创建 RmoteViews
46         RemoteViews view = new RemoteViews(context.getPackageName(),R.layout.widgetprovider_layout);
47         // 设置Widget中Button被按下的事件
       // *** 这是定义 RemoteViews 中控件事件的方法, 就是当它被点击时去执行一个 PendingIntent. ***
         48 view.setOnClickPendingIntent(R.id.button1, pIntent); 49 50 for (int i = 0; i < appWidgetIds.length; i++) { 51 // 使用 appWidget管理者,更新Widget 52 appWidgetManager.updateAppWidget(appWidgetIds[i], view); 53 }
      

        // 可以不使用循环.直接将这个 appWidgetIds数据传入即可. 使用 appWidget管理者,更新Widget
        // appWidgetManager.updateAppWidget(appWidgetIds, view);

54     }
55 }

  这里我们只实现的它的onUpdate 方法

4. 要在我们的 Manifest 的 application 标签中注册一个 receiver 

1         <receiver android:name="MyAppWidgetProvider">
2             <intent-filter>
3                 <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
4             </intent-filter>
5             
6             <meta-data 
7                 android:name="android.appwidget.provider"
8                 android:resource="@xml/widgetprovider_info" />
9         </receiver>

   这里为什么 receiver 呢? 因为Widget其实相当于一个 广播接收器, 它使用 onReceive() 方法,来处理接收到的Intent.

OK 完成了 上面4个步骤, 就会成功的创建了我们自己的Widget了~ 

 

这里. 再写些 在Receive中更新内容时 需要的一些知识 : 

  1. 因为 AppWidget 与我们的程序不在一个进程中. 所以更新操作也需要使用 RemoteViews

    // 比如: 更新 AppWidget上一个 TextView中的内容 : remoteViews.setTextViewText(R.id.textview1,"xxx");

1             // 更新 RemoteViews
2             RemoteViews view = new RemoteViews(context.getPackageName(),R.layout.widget_layout);
3             // 更新 TextView 中的内容
4             view.setTextViewText(R.id.textView1, "Receive Broadcast");

  2. 更新AppWidget 需要使用 AppWidgetManager

1             // 得一个用来一个用来更新的 AppWidget的管理者
2             AppWidgetManager manager = AppWidgetManager.getInstance(context);

  3.AppWidgetManager 需要通过  ComponentName 知道你要更新 哪种 AppWidget,

1             // AppWidgetManager 需要通过 ComponentName 知道你想更新哪种 AppWidget
2             ComponentName componentName = new ComponentName(context,MyAppWidgetProvider.class);

  4. 使用 AppWidgetManager 更新 

1             manager.updateAppWidget(componentName, view);

 

 

效果如下:

  

posted @ 2013-03-22 16:36  easyfrog  阅读(337)  评论(0编辑  收藏  举报