Android app 实现AppWidget 窗口部件开发

一,描述

  在很多情况下,我们都需要自己的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 有点啰嗦。)

 

 

你可能感兴趣的:(appwidget)