android自定义桌面挂件widget用法(一)

因公司项目需要,今天简单研究了一下桌面挂件widget的实现,写一篇总结一下思路,如有理解错的地方,望指出!

一般而言,简单的桌面挂件,如仅使用到Button, ImageView, TextView 之类的布局,只需遵循三步走:
第1步:在layout布局下编写 widget_layout.xml,定义挂件布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:orientation="vertical" 
    android:gravity="center_horizontal"
    android:background="@drawable/dialog_loading_bg">
    <ImageView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/recorder"/>
LinearLayout>

布局太简单就不废话了。

第二步:在res/xml/目录下创建一个 weiget_info.xml ,定义该挂件的属性

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="300dp"
    android:minHeight="200dp"
    android:initialLayout="@layout/widget_layout"
    android:updatePeriodMillis="0" 
    android:previewImage="@drawable/recorder">
appwidget-provider>

android:updatePeriodMillis=”0” 据说这个属性在sdk1.0之后就取消了,因此挂件的更新要自己去实现了; android:previewImage=”@drawable/recorder” 设置挂件在系统中用户选择widget的预览框中看到的预览效果图; android:initialLayout=”@layout/widget_layout”绑定该widget挂件的布局文件即步骤一的文件;

第三步:自定义APPWidgetProvider子类

public class WidgetProvider extends AppWidgetProvider {

    //创建更新widget时触发
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        int widgetId = appWidgetIds[0];
            //声明一个pendingIntent对象指定跳转的目标界面
            Intent intent = new Intent(context, SecondActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
            //为RemoveView加载布局并为该布局内部控件设置点击跳转的监听
            RemoteViews view = new RemoteViews(context.getPackageName(),R.layout.widget_layout);
            view.setOnClickPendingIntent(R.id.layout, pendingIntent);

            appWidgetManager.updateAppWidget(widgetId, view);//用appwidgetmanager回调update方法
    }
    //删除widget时触发
    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        super.onDeleted(context, appWidgetIds);
    }

    //接受特定广播时触发
    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
    }

}

关于AppWidgetProvider需要清楚的是:AppWidgetProvider实质上是一个广播类,拥有广播的所有属性,可以理解为他其实是一个有界面的广播,其界面就是这个widget挂件。widget通过appwidgetprovider广播来实现布局,刷新,跳转等操作。

在这个子类里,onUpdate方法一般都要复写, onDelete方法及onReceive,onEnable,onDisable方法则可根据需求选择性的复写。

在onUpdate方法里,把weiget_layout.xml 布局文件分配给RemoteView,出此之外,还可以定义remoteView的点击触发事件PendingIntent,用PendingIntent.getActivity(mContext.getPagerName(),0,new Intent(mContext,指定的界面.class),0)的对象pendingIntent,remoteView.setOnClickPendingInent(R.id.某控件,pendingIntent);实现指定界面的跳转。方法的最后用appwidgetmanager调用updateWidget(widgetId,remoteView)方法刷新。

最后还有一个点睛之笔:Mainfest.xml文件中注册自定义的appwidgetprovider子类(广播类)

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <receiver 
            android:name=".ListWidgetProvider">
            <intent-filter> 
          <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
              <action android:name="android.appwidget.action.APPWIDGET_DELETE"/>
        intent-filter> 
            <meta-data 
                android:name="android.appwidget.provider" 
                android:resource="@xml/widget_info"/>
        receiver>
        <application/>

receive 内部声明该广播的名称,android:name=”.自定义的widgetprovider”, 在intent-filter里面声明该widget要接收的两个系统的广播,分别是update和delete,在meta-data内部指明该类属于android.appwidget.provider(安卓系统挂件广播类),并绑定其挂件的属性文件widget_info.xml,即是步骤二的文件。

好啦,大功告成啦哈哈~

你可能感兴趣的:(android开发)