android widget的研究(一)

新进了一个项目组, 有个需求是要求在桌面上有个widget直接提用户操作,而不必麻烦每次用户进入应用去设置某些东西.!

关于如何订制widget, 官方文档的位置:/guide/topics/appwidgets/index.html

一:什么是app widget?

官方的解释翻译来就是:  ()窗口小部件(Widget)是微小的应用程序视图,可以被嵌入到其它应用程序中(比如桌面)并接收周期性的更新。你可以通过一个App Widget provider来发布一个Widget。可以容纳其它App Widget的应用程序组件被称为App Widget宿主。

二:如何订制自己的widget.?

订制自己的widget很容易-----

1:在AndroidManifest.xml中配置我们的Widget, 从官方文档我得知其实所谓widget其实就是一个BroadcastReceiver, 而我们所继承的AppWidgetProvider继承了BroadcastReceiver,所以我更加确信了它就是一个广播接受者

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

2: 添加AppWidgetIInfo MetaDate(元数据)

在/res/xml文件夹下新建一个widget_info.xml文件, 取这个名字是因为我在receiver中配置<meta-data>的时候就是写的widget_info, 取什么名字都是可以的, 只是<meta-data>的android:resource属性相应的引用就可以了!

<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider
    android:minWidth="294dp" 
    android:minHeight="72dip" 
    android:updatePeriodMillis="600000" 
    android:initialLayout="@layout/my_widget"
    xmlns:android="http://schemas.android.com/apk/res/android" />
关于<appwidget-provider>的一些属性设置, 不过多的解释了, 网上一搜一堆, 不过个人还是推荐看官方文档, 说的已经够详细了, 例如这个最小的宽和高怎么算之类的都有

3: 为widget创建layout, 这里在/res/layout文件夹下创建my_widget.xml, 与上面的保持一致

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal" android:layout_width="294dp"
	android:layout_height="72dp" android:background="@drawable/widget_shape"
	android:gravity="left|center_vertical">
        <Button android:layout_width="wrap_content" android:text="widget_button" android:id="@+id/button"
        android:layout_weight="1" android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_height="fill_parent" android:gravity="left" />
	<TextView android:layout_width="wrap_content" android:id="@+id/tvName"
		android:textAppearance="?android:attr/textAppearanceLarge"
		android:layout_height="fill_parent" android:gravity="left"></TextView>
</LinearLayout>

注意: 这里我自己给布局加了个背景, 而这个背景是一个渐变颜色, 是自己在/drawbale文件夹下创建了一个widge_shape.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> 
    <gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF" 
            android:angle="270"/> 
    <padding android:left="50dp" android:top="20dp" 
            android:right="7dp" android:bottom="7dp" /> 
    <corners android:radius="8dp" /> 
    
</shape> 

4: 创建MyWidget类

public class MyWidget extends AppWidgetProvider {
	
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.my_widget);
        String name = "my first widget";        
        remoteView.setTextViewText(R.id.tvName, name);
        appWidgetManager.updateAppWidget(appWidgetIds, remoteView);
		//super.onUpdate(context, appWidgetManager, appWidgetIds);
	}
	
}
这里没有调用super.onUpdate()是因为我跟源码进去看了, 父类的这个方法是个空实现, 所以没必要调用

做到这里的时候, 被button的点击事件卡了一下, broadcastReceiver是不能像Activity那样获取到按钮并且为其设置onClick事件的, 也无法在xml中为Button设置android:onClick属性! 我很着急, 于是我静下心来继续读文档,  发现文档上有教阿, 所以在资料甚少的时候, 挖掘官方文档绝对是正解!

文档中点击的时候是去打开一个Activity, 而我这里是做demo,只想它弹一个Toast就够了, 所以我选择调用一个服务!

在onUpdate中添加如下代码:

Intent intent = new Intent(context, MyService.class);
        PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
        remoteView.setOnClickPendingIntent(R.id.button, pendingIntent);

我没有跟这个setOnClickPendingIntent的源码, 因为我猜也猜的出来这个方法就是让你去指定widget中某个控件的点击事件,  我在想, 这个RemoteViews会提供这个方法的原因是我们无法像在Activity中那样去指定点击事件, 如果没有这个API去指定, 那widget中的按钮就将无法点击(当然google早考虑到了!)

至于Service的代码就不贴了, 里面就一句代码:Toast.make().show();而已!

说一下:如果你向我上面没有什么特殊需求,那么重写Service的onCreate()方法就可以了, 但是当我们用PendingIntent去让别人启服务的时需要用到Intent的话, 到底是该重写onStart()还是onBind()呢.?   答案是应该重写onStart方法,  因为在官方文档PendingIntent.getService()处该方法的描述是:

Retrieve a PendingIntent that will start a service, like calling Context.startService(). The start arguments given to the service will come from the extras of the Intent.


文档上还说可以创建配置widget的Activity, 可以从配置Activity中更新widget等.  这次就研究到这里, 基本上有这类需求的童鞋应该够用了! 如果满足不了的话自己读读文档应该能出来,  懒得读的话就期待我下一篇研究widget的文章


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值