zoukankan      html  css  js  c++  java
  • android widget的中文文档

    下文是我翻译于 App Widgets的文章,如果有不当之处请大家指出


    app widget是一种嵌入在其他应用(例如主屏幕)和并且能偶接受间接性更新的小应用,你可以自己提供app widget provider 来在用于界面上定义app widget,包含了app  widget的应用程序组件叫做app widget host.


    1.基础的工作

    AppWidgetProviderInfo 对象

    描述了app widget 所需的元数据,例如app widget 的布局,更新的频率 和实现AppWidgetProvider的类,这些都应该定义的XML文件夹中。


    继承实现AppWidgetProvider对象

         定义了一些基本的方法,这些方法能够让你与app widget进行交互,这些方法都是基于android的广播事件,当你的app widget调用updated(),enabled(),disabled()和delete()的方法的时候都会接收到广播。


    2.在AndroidManifest.xml文件中进行相应的配置

        首先需要在AndroidManifest.xml中声明你自己实现的AppWidgetProvider类,如下

    <receiver android:name="ExampleAppWidgetProvider" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data android:name="android.appwidget.provider"
                   android:resource="@xml/example_appwidget_info" />
    </receiver>


         <receiver>标签需要指定android:name这个属性,这个标签指定了你自己继承实现AppWigetProvider的类,同时你还要在<intent-fliter>这个标签中指定一个包含android:name的标签,这个标签表示将会去过滤会包含了ACTION_APPWIDGT_UPDATE的广播,这是唯一一个是你必须要明确指定接受的广播,系统的AppWidgetManager将会自动的将app widget广播发送到需要接受的AppWidgetProvider的实现类中。

    <meta-data>元素指定了AppWidgetProviderInfo的信息并且必须包含下面两个信息。

    android:name:这个属性指定了元数据的名称。使用android.appwidget.provider来指定数据作为AppWidgetProviderInfo的描述信息。

    anndroid:resources 来指定AppWidgetProviderInfo描述信息的位置。


    3.添加AppWidgetProviderInfo的元数据

    AppWidgetProviderInfo定义了App Widget的基本信息,例如布局尺寸的最小值,和初始化布局文件的资源,更新app widget的频率,同时你还可以定义在创建widget的时候启动一个activity,这一项是可选的。你需要在res下新建一个xml目录,在这个目录中创建一个xml文件,这个xml文件的根元素必须要是<appwidget-provider>,例如下面的例子。

    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:minWidth="294dp"
        android:minHeight="72dp"
        android:updatePeriodMillis="86400000"
        android:initialLayout="@layout/example_appwidget"
        android:configure="com.example.android.ExampleAppWidgetConfigure" >
    </appwidget-provider>

        下面是对xml文件中元素的说明

          minWidth和minHeight属性指定了app widget布局文件所需要最小尺寸。

          在主屏幕上放置的app widget取决于定义了宽和高的网格,如果我们自定义的最小宽或者高不和屏幕网格中的格子不匹配,那么app widget的尺寸会自动的变成与当前格子最匹配的尺寸,因为屏幕的方向是可以改变的,因此网格格子尺寸大小也是可以变化的,所以建议你假设格子的宽和高的值为74像素,同时,你应该从最终的尺寸计算中减去2,因为可能会出现的像素计算问题。为了计算出最佳的宽和高,建议你使用下面的公式。

    (number of cells * 74) - 2

    因此,可以使用72来作为一个app widget的高,使用294来作为一个app widget的宽,宽度包含了四个格子。

             updatePeriodMillis属性定义了app widget要求调用AppWidgetProvider 实现类的onUpdate方法的频率。但是并不能保证能够在准确的时间去调用这个更新方法,我们建议这个更新的周期越大越好,从省电的角度来看,一个小时不要超过一次。你也应该允许用户去配置这个调用的周期,例如有人需要每一刻钟去更新证券的信息,有的人可能一天只更新四次。注意:如果到了更新的时候,设备正处于休眠期,那么设备将会被唤醒去完成这次更新。如果你一个小时以内更新的频率低于一次,那么这将不会对你的电池造成什么明显的影响,如果你更新的十分频繁,或者不需要在设备休眠的时候更新,那么建议你使用闹钟来完成这个功能,在闹钟中你可以设定是否需要唤醒设备。你可以设定闹钟的类型为ELAPSED_REALTIME或者RTC,这将只在设备处于唤醒状态进行更新。那么在这种情况下,你可以设定updatePeriodMillis为0

    initiaLayou属性指定了app widget的布局文件。

    configure属性指定了当用户创建一个app widget的时候需要启动的activity,这个属性允许用户去设定app widget的属性.。这一项是可选的。


    4.创建App Widget的布局文件

    必须定义一个在res/layout中定义一个布局文件,来作为app widget的初始化布局文件。你可以使用下面列表中出现的View对象来作为布局文件。

    如果你属性创建布局文件,那么创建一个app widget的布局文件同样是一个很简单的事情,但是需要注意的事情是app widget的布局是基于RemoteViews的,这些并不是支持所有的布局文件,只有下面三种是被支持的:FrameLayout,LinearLayout和RelativeLayout,同时下面这七种Widget对象也是被支持的:AnalogClock,Button,Chronometer,ImageButton,ImageView,ProgressBar和TextView。



    5.使用AppWidgetProvider class

          AppWidgetProvider 类继承了BroadcastReceiver,这样方便于去处理App Widget广播,AppWidgetProvider类只处理与App Widget相关的广播,例如当app widget 发生以下的事件updated,deleted,endabled和disabled。当这些广播事件发生以后,AppWidgetProvider会调用这些方法

         onUpdate(Context context,AppWidgetManager,int [] widgetids) 这个方法会在updatePeriodMillis属性定义的时间周期类调用,当用户添加新的App Widget的时候,这个方法也会被调用。因此在这个方法里面需要执行一些必要的设置,例如设定一个视图的事件处理器或者启动一个临时的服务。但是,如果你为app widget添加了启动的activity,那么在用户添加app widget的时候,这个方法不会被执行,但是在随后的更新中,这个方法会被执行。在完成配置任务的activity完成配置的时候要执行一次更新。

         onDeleted(Context context,int [] widgetsid)每当App Widget被删除的时候调用

         onEnabled(Context context)这个方法只会在第一次创建app widget的时候被调用,例如,当用户创建了两个app widget,这个方法只会在创建第一个app widget的时候被调用,如果你需要使用数据库或者其他只需要只执行一次的设定,那么你可以将它们放在这个方法里面调用。当最后一个app widget实例被删除的时候,这个方法会被调用。在这里你可以完成一些必要的清理工作。

          onReceive(Context context,Intent intent)这个方法在收到关于app widget的广播之后并且在上面所有的方法调用之前被调用,实际上你并不需要自己去实现这个方法,因为在AppWidgetProvider提供的默认实现中,会根据系统的广播来在上面的方法选择一个调用。

    在AppWidgetProvider所有的方法中最重要的是Onupdate方法,因为每次添加一个app widget的都会被调用,除非你为你的app widget配置了一个activity.如果你的app widget需要处理与用户的交互事件,那么你也许需要在这个方法中定义一个事件处理的handler,如果你的app widget不需要创建临时性的文件或者其他需要在最后处理的任务,那么你或许仅仅需要在onupdate中来定义自己业务处理逻辑,其他的方法空实现即可。例如,当你的app widget中包含一个button,当点击button的时候,需要启动一个activity,那么下面的示例可以供你参考。

    public class ExampleAppWidgetProvider extends AppWidgetProvider {
    
        public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            final int N = appWidgetIds.length;
    
            // Perform this loop procedure for each App Widget that belongs to this provider
            for (int i=0; i<N; i++) {
                int appWidgetId = appWidgetIds[i];
    
                // Create an Intent to launch ExampleActivity
                Intent intent = new Intent(context, ExampleActivity.class);
                PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
    
                // Get the layout for the App Widget and attach an on-click listener to the button
                RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
                views.setOnClickPendingIntent(R.id.button, pendingIntent);
    
                // Tell the AppWidgetManager to perform an update on the current App Widget
                appWidgetManager.updateAppWidget(appWidgetId, views);
            }
        }
    }

    这个AppWidgetProvider实现类仅仅定义了onupdate方法,在这个方法中我们定义了一个可以启动activity的PendingIntent,我们点击了注册了setOnClickPendingIntent()方法的button时,会启动我们定义的activity.需要注意的是,在这个方法里面包含了对appwidgetids数组的遍历,这个数组是当我们创建app widget的时候AppWidgetProvider为我们创建的。 此外,当用户创建了不止一个app widget的时候,这些app widget会全部同时的更新。但是针对更新的频率我们只能定义一个updatePeriodMillis属性。例如当我们设定更新周期为两个小时一次,我们创建两个app widget之间相隔了一个小时,那么第二个被添加的app widget也会在第一个app widget 被添加两个小时之后更新。第二个的更新周期会被忽略。

           注意:因为AppWidgetProvider是继承与BroadcastReceiver,你的进程在这些方法返回之后并不能保证会继续执行,如果你的进程需要进行耗时的操作,那么请考虑一下在onupdate方法中启动一个service,在这个service中,你可以考虑继续进行你需要完成的工作而不需要担心ANR


    6.接收到的App Widget 广播意图

    AppWidgetProvider是一个方便用来处理接收到的AppWidget 广播的类。如果你需要直接接受到App Widget的广播,那么你可以实现你自己的BroadcastReceiver或者重写onReceiver方法。下面这四种意图是你需要关心的。

    ACTION_APPWIDGET_UPDATE   ACTION_APPWIDGET_DELETED ACTION_APPWIDGET_ENABLED  ACTION_APPWIDGET_DISABLED


    7.为app widget 添加启动的activity

    如果你想在用户创建一个app widget的时候可以配置app widget的基本信息,你可以为app widget配置一个activity,用户可以通过这个activity来配置widget 的更新频率,大小,颜色或者其他功能性的设置。

    这个配置性的Activity同样需要在AndroidManifest.xml文件中进行声明,但是这个activity需要对android.appwidget.action.APPWIDGET_CONFIGURE 进行过滤。如下面的示例

    <activity android:name=".ExampleAppWidgetConfigure">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
        </intent-filter>
    </activity>

    同样需要在AppWidgetProviderInfo xml文件中定义这个activity的信息。示例如下:

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

    类的名称一定是全限定名称,因为你可能引用了其他包的类。这些就是启动activity所需要的。现在你需要的就是一个继承了Activity的类,但是你还需要注意下面两点。

    ①这个activity需要返回一个结果,这个结果中包含了intent传递过来的App Widget ID

            ②当app widget被创建的时候 onupdate方法不会被执行,因为在启动activity的时候,系统不会发出 ACTION_APPWIDGET_UPDATE广播,那么当加载activity之后,activity需要主动去要求一次更新app widget。否则出了第一次会被跳过意外,后面的更新会被执行。

    下面给出了配置activity实现。


    8.通过activity更新app widget

        如果创建app widget的时候使用了activity,那么在activity配置结束的时候应该主动要求更新一次app widget。可以通过AppWidgetManager来完成一次更新的请求。

    下面是要求更新app widget的步骤。

    ①首先通过启动Activity的intent 获取App Widget id

     

    Intent intent = getIntent();
    Bundle extras = intent.getExtras();
    if (extras != null) {
        mAppWidgetId = extras.getInt(
                AppWidgetManager.EXTRA_APPWIDGET_ID, 
                AppWidgetManager.INVALID_APPWIDGET_ID);
    }

    ②完成用户配置的设置。

    ③当配置完成以后,通过调用AppWidgetManager的getIntance(Context context)来得到AppWidgetManager的实例。

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

    ④通过RemoteViews并且调用AppWidgetManager实例的updateAppWidget方法来完成更新。

    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
    appWidgetManager.updateAppWidget(mAppWidgetId, views);

    ⑤最后创建一个返回的Intent

    Intent resultValue = new Intent();
    resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
    setResult(RESULT_OK, resultValue);
    finish();


    上面的翻译来自于个人的理解,部分语言实在是不知道怎么翻译,希望大家多多指点。
























  • 相关阅读:
    Delphi 的字符及字符串 Char、AnsiChar、WideChar、PChar、PAnsiChar、PWideChar
    C# DllImport的用法
    delphi 枚举类型与字符串的转换
    MSSQL2005不能用IP访问
    Delphi制作DLL
    Delphi接口的底层实现
    MacBook下每次SourceTree每次拉取代码都要输入密码解决办法
    因子分析AF
    蒲公英组网
    485通信
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3481538.html
Copyright © 2011-2022 走看看