AppWidget学习心得

AppWidget就是我们平常在桌面上见到的那种一个个的小窗口,利用这个小窗口可以给用户提供一些方便快捷的操作。本文通过创建AppWidget过程来说明如何创建一个AppWidget

1) 创建AppWidget配置文件

首先要在工程文件中的res文件夹中创建一个xml文件夹,在xml文件夹中创建一个appwidget_config.xml的配置文件,具体代码如下:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"

    android:initialLayout="@layout/widget_ui"

    android:minHeight="140dip"

    android:minWidth="140dip"

    android:updatePeriodMillis="6890000" >

 

</appwidget-provider>

这个xml是用来描述所要创建的appWidget的一些描述信息的,所描述的属性分别有最小高度、最小宽度、刷新间隔和关联布局文件布局文件。特别要说的是AppWidget的大小是以格为单位来计算的,手机屏幕被分为一个4*4的格阵,当宽高到达一定值时就会显示并占满相应的格数,不会出现自定义不规则的大小的。网上资料显示说N格的长宽为(74*N-2。我设定的140*140显示的是2*2的界面。

2) 创建布局文件

res文件夹中的layout文件夹中创建一个layout布局文件,用于绘制AppWidget的界面。我这里绘制了一个图片视图和3个按钮。具体代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:background="#AA000000"

    android:orientation="vertical" >

    <ImageView

        android:id="@+id/img_widget"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:background="#AAAAFFFF" />

    <LinearLayout

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:orientation="horizontal" >

        <Button

            android:id="@+id/btn_provious"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="-1"

            android:textColor="#FFFFFF" />

        <Button

            android:id="@+id/btn_play"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="0"

            android:textColor="#FFFFFF" />

        <Button

            android:id="@+id/btn_next"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="+1"

            android:textColor="#FFFFFF" />

    </LinearLayout>

</LinearLayout>

功能是点击不同的按钮会显示不同的图片。其界面图如下:

 

3) 创建java工程文件

其实第三第四步是同时进行的,在工程的src文件夹中创建AppWidget.java文件继承自AppWidgetProvider,并重写父类中的方法。

这个类定义了AppWidget的基本生命周期函数,具体如下:

onEnabled(Context)  当AppWidget实例第一次被创建时调用。

onReceive(Context, Intent)   接收广播事件。

onUpdate(Context , AppWidgetManager, int[] appWidgetIds)  到达指定的更新时间或用户向桌面添加widget时候调用。

onDeleted(Context, int[] appWidgetIds)  当AppWidget被删除时调用。

onDisabled(Context)  当最后一个AppWidget被删除时调用。

个人心得:onUpDate方法用于创建和更新AppWidget,将所需的ID通过intent进行传递。onReceive方法通过接收intent传送的广播事件实现AppWidget的变化操作。这两个方法在AppWidget的编写中至关重要。

4) 修改AndroidManifest文件

想要让AppWidget显示在手机界面上,还需要在AndroidManifest文件中进行注册。注册信息如下:

 <receiver android:name="MyAppWidget" >

  <meta-data

  android:name="android.appwidget.provider"

android:resource="@xml/appwidget_providerinfo" />

<intent-filter>

<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />

<action android:name="image.one" />

<action android:name="image.two" />

<action android:name="image.three" />

</intent-filter>

</receiver>

receive中添加meta-data注册AppWidget的配置信息文件,添加intent-filter用于添加所需intent,这里的action按照需要添加。我需要3intent来切换3张图片所以在这里定义了3action

5) 实现功能

到上面一步,我们在手机上添加自定义的AppWidget已经可以正常显示了,之后我们来实现功能逻辑。

正如上面所说的,我们用到了onUpDateonReceive方法。

@Override

public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {

for (int i = 0; i < appWidgetIds.length; i++) {

int appWidgetId = appWidgetIds[i];

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

Intent intent1 = new Intent("image.one");//定义intent

Intent intent2 = new Intent("image.two");

Intent intent3 = new Intent("image.three");

PendingIntent pendingIntentOne = PendingIntent.getBroadcast(context, 0, intent1, 0);//PendingIntentIntent包裹起来

PendingIntent pendingIntentTwo = PendingIntent.getBroadcast(context, 0, intent2, 0);

PendingIntent pendingIntentThree = PendingIntent.getBroadcast(context, 0, intent3, 0);

views.setOnClickPendingIntent(R.id.btn_provious, pendingIntentOne);//按钮点击事件监听

views.setOnClickPendingIntent(R.id.btn_play, pendingIntentTwo);

views.setOnClickPendingIntent(R.id.btn_next, pendingIntentThree);

//更新AppWidget

appWidgetManager.updateAppWidget(appWidgetId, views);

}

}

在onUpDate方法中用到了RemoteViews与PendingIntent, 是因为AppWidget和其原本的App并不在同一个进程中,而是运行在HomeScreen进程当中,因此,在控件监听器的绑定,更新等操作都会与以前基本的方法有所不同。

PendingIntent是一个特殊的Intent,实际上它像一个邮包,其中包裹着真正的Intent,当邮包未打开时,Intent是被“挂起”的,所以并不执行,只有当邮包拆开时才会执行。它与Intent的区别在于:Intent 是及时启动,intent 随所在的activity 消失而消失。 进程A创建PendingIntent,发送给进程B,进程B此事并不执行,直到用户出发某一事件时,包裹被拆开,里面的Intent真正执行。所以Intent什么时候被执行是不知道的,由用户出发事件来决定。

RemoteViews表示了一系列view对象,即AppWidget所有的控件。它的应用方法如上源码所示,使用了views.setOnClickPendingIntent(所需控件的ID,定义的pendingintent)方法来为控件绑定监听器。

以下是onReceive方法,用于实现切换图片功能。

@Override

public void onReceive(Context context, Intent intent) {

super.onReceive(context, intent);

ComponentName thiswidget = new ComponentName(context,MyAppWidget.class);//定义容器

RemoteViews views = new RemoteViews(context.getPackageName(),

R.layout.appwidget_ui);//定义RemoteViews 

//定义AppWidgetManager,用于之后更新AppWidget

AppWidgetManager appWidgetManager = AppWidgetManager

.getInstance(context);

views.setImageViewResource(R.id.img_widget

R.drawable.dmkamsndymzzz);

//通过Intent判断点击的哪个按钮,并作出反应

if (intent.getAction().equals("image.one")) {

//更新图片

views.setImageViewResource(R.id.img_widget

R.drawable.syfj631139232);

}

if (intent.getAction().equals("image.two")) {

views.setImageViewResource(R.id.img_widget

R.drawable.syrx2623204137);

}

if (intent.getAction().equals("image.three")) {

views.setImageViewResource(R.id.img_widget

R.drawable.dmkamsndymzzz);

}

//更新AppWidget

appWidgetManager.updateAppWidget(thiswidget, views);

}

代码具体功能都已注释。从上源码中可以看到IntentAppWidget中的作用。

由于AppWidget与以往的程序有所不同,需要花一段时间去理解。我觉得最重要的是理解PendingIntentRemoteViews,了解IntentAppWidget中的重要作用。

你可能感兴趣的:(源码,android,实例,界面,widget)