Android AppWidget三部曲之初级篇

Android -- AppWidget 初级篇
 一个简单的AppWidget
最近在写日历AppWidget(小部件)代码,遇到很多问题,AppWidget所支持的操作和View实在有限,动画效果根本不支持,就连Intent启动Activity、Service,和在TextView上显示简单的“HellWord”都显得变态。实现了日历小部件的日历显示、Button事件、翻页动画效果、onTouch事件等功能。下面就将整理的资料和自己的实践写了下来:

其实Appwidget是一个小型的Views,可以嵌入到其他应用程序并且定期更新。这些View被称为Widgets组件,您可以通过AppwidgetProvider去发布Widgets,能够容纳其他Appwidget的称为Appwidget host。


1.1 在AndroidManifest.xml中注册AppWidget
<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属性,它指定Appwidget所使用的AppwidgetProvider.

<intent-filter>至少需要包含 android:name="android.appwidget.action.APPWIDGET_UPDATE",这个属性指定AppwidgetProvider接收APPWIDGET_UPDATE广播,这是唯一一个需要明确声明的广播。当需要时,AppWidgetManaget自动给所有Appwidget发生广播.

<meta-data>指定了AppwidgetProviderInfo资源,需要一下属性:android:name  指定metadata的名字。使用android.appwidget.provider将其作为AppwProviderInfo的描述性数据

Android:resource 指定AppwidgetProviderInfo资源的位置


1.2 增加AppwidgetProviderInfo Metadata
一个Appwidget的基本属性是通过AppwidgetproviderInfo去定义的,例如它的最小尺寸的布局,它的初始layout,多久更新Appwidget,还有(可选)在创建时期配置一个Activity。在xml资源中定义一个AppwidgetproviderInfo是通过<appwidget-provider>标签,并保存在工程的res/xml/文件夹下,例如:

(AppWidget特有的配置文件)  
  
<?xml version="1.0" encoding="utf-8"?>  
  
<appwidget-provider   
  
xmlns:android="http://schemas.android.com/apk/res/android"  
  
    android:minWidth="220dp"  
  
    android:minHeight="220dp"  
  
    android:updatePeriodMillis="86400000"  
  
    android:initialLayout="@layout/firstappwidget"  
  
Android:configure="com.example.android.ExampleAppWidgetConfigure"/>  
updatePeriodMillis属性定义了Appwidget应该多久向Appwidgetprovider请求更新。实际更新的时间未必能保证及时更新,并且建议尽量不要频繁更新。
Configure属性是当用户添加一个AppWidget前启动一个Activity,这个Activity的作用就是配置Appwidget的属性。

 
1.3 为Appwidget定义layout
只要你属性用xml怎么去定义layout的话,为appwidget定义一个layout还是很简单的。但是由于Appwidget的布局是基于RemoteVIew,所以只能使用RemoteViews(后面篇章将会对RemoteViews做详细分析)所支持的 layout(FrameLayout,LinearLayout,RelativeLayout)或者view(AnalogClock, Button , Chronometer ,ImageButton, ImageView, ProgressBar, TextView注意:继承这些类的子类同样不支持)。

 
1.4 使用Appwidgetprovider
Appwidgetprovider是BroadcastReceiver的子类,这个类处理Appwidget的广播。

Appwidgetprovider只接受于Appwidget有关系的广播,比如Appwidget在update,deleted,enabled,disable。当这些广播发生的时候,AppWidgetProvider会调用一下回调方法:

onUpdate(Context, AppWidgetManager, int[]) 

间隔调用此方法去更新Appwidget,间隔时间的设置时在AppwidgetproviderInfo下的updatePeriodMillis属性,同样当用户添加Appwidget的时候也被调用。如果你已经声明了一个configuration Activity,用户添加Appwidget的时候就不会调用onUpdate,但是随后的更新中依然会被调用。

onDeleted(Context, int[])

当Appwidget从Appwidget host中删除的时候调用

onEnabled(Context);

当Appwidget第一次创建的时候调用。比如,当用户增加两个同样的Appwidget的时候,这个方法只在第一次去调用。如果你需要打开一个新的数据库或者其他的设置,而这在所有的Appwidget只需要设置一次的情况下,这个是最后的地方去实现它们。

onDisabled(Context)

当Appwidget的最后一个实例从Appwidget host中删除的时候调用。这里可以做一些在onEnabled(Context)中相反的操作,比如删除临时数据库。

onReceive(Context, Intent)

每一个广播的产生都会调用此方法,而且是在上面方法之前被调用。通常不需要实现此方法(这个方法在后面会作详细分析)。

在AppwidgetProvider中最重要的callback就是onUpdated(),如果你的Appwidget接受用户交互事件,就需要在这个callback里面进行处理。

如果你需要一个带有Button的Appwidget,点击Button去启动一个Activity,下面就是AppwidgetProvider的实现方法:

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 tothe 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   
    WidgetappWidgetManager.updateAppWidget(appWidgetId, views);  
}  
}  

1.5 创建Appwidget Configuration Activity
这个Activity将通过Appwidget自动启动,用户可以给Appwidget设置有用的参数,比如Appwidget的颜色,大小,更新时间或者其他的属性。

在AndroidManifes.xml中定义这个Activity和一般定义Activity基本没有区别,Appwidget host启动这个Activity需要一个Action,所以:

<activity android:name=".ExampleAppWidgetConfigure">  
<intent-filter>  
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>  
</intent-filter>  
</activity>  
同样这个Activity必须在AppwidgetProviderInfo XML文件中定义android:configure.

值得注意的是Appwidget host调用configuration Activity,configuration Activity必须要返回一个结果(必须包含Appwidget ID)saved in the Intent extras as EXTRA_APPWIDGET_ID


1.6 通过configuration Activity去更新Appwidget
获取Appwidget ID

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

设置Appwidget参数

设置完成,通过getInstance(Context)获取AppwidgetManager实例

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 

通过调用updateAppWidget(int,RemotrViews)去更新Appwidget

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

创建一个返回的Intent,结束Activity

Intent resultValue = new Intent();  
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,mAppWidgetId);  
setResult(RESULT_OK, resultValue);  
android:initialLayout="@layout/firstappwidget"指定了下面的布局文件firstappwidget.xml
<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"   
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent">  
<TextView android:id="@+id/tvMsg" android:layout_width="fill_parent"  
    android:layout_height="wrap_content" android:textSize="20dp"  
    android:textColor="#F00"/>  
</LinearLayout>  
一个完整的AppWidget已经完成。麻雀虽小五脏俱全,所有Appwidget都保护有以上4个部分。接接下来让我慢慢解释。

本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2012-06/63269.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值