widget模板

[功能]

widget开发和别的应用程序还是有点不同的 因为其使用比较麻烦 所以今天打算建一个widget模版 把一些固定的东西写死 而把具体定制化内容 的地方 告诉大家 以后要使用的话 直接移过去就可以了

[思路]

1. 一个最基本的widget 的内容

2. 扩展内容 包括:

* startActivity(Intent)

* sendBroadcast(Intent)

[代码 步骤]

1. 创建无用的 initialActivity 用途是:运行该应用程序用 设置其属性为:

Xml代码 复制代码 收藏代码
  1. <activityandroid:name=".initialActivity"
  2. android:label="@string/app_name">
  3. <intent-filter>
  4. <actionandroid:name="android.intent.action.MAIN"/>
  5. <categoryandroid:name="android.intent.category.LAUNCHER"/>
  6. </intent-filter>
  7. </activity>
<activity android:name=".initialActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

2. 定义该woidge 所包含的View 及 布局 wlayout.xml :

Xml代码 复制代码 收藏代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="horizontal"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <TextView
  8. android:id="@+id/text"
  9. android:textSize="12px"
  10. android:textStyle="bold|italic"
  11. android:textColor="#008800"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"/>
  14. <Button
  15. android:id="@+id/next"
  16. android:text="Next!"
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"/>
  19. </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    android:id="@+id/text"
    android:textSize="12px"
    android:textStyle="bold|italic"
    android:textColor="#008800"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
<Button
    android:id="@+id/next"
    android:text="Next!"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

2. 定义该widget所需的属性文件 R.xml.wattra.xml 包括:

写道
1. 占用大小
2. 更新频率
3. 布局文件

Xml代码 复制代码 收藏代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <appwidget-providerxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:minWidth="246dip"
  4. android:minHeight="22dip"
  5. android:updatePeriodMillis="1000"
  6. android:initialLayout="@layout/wlayout"/>
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="246dip"
    android:minHeight="22dip"
    android:updatePeriodMillis="1000"
    android:initialLayout="@layout/wlayout" />

3. 在提及widget之前 说说widget 的原理

写道
1.其实 widget 也是一种 BroadcastReceiver

2.其action = “android.appwidget.action.APPWIDGET_UPDATE”
写道
所以 我们的工作就是: 实现 AppWidgetProvider 的方法:
void onUpdate(Context context,
AppWidgetManager appWidgetManager,int[] appWidgetIds)


但是 因为 AppWidgetProvider 特殊上下文Context 的缘故 很多方法不可用

所以 我们打算把具体的刷新工作放在Service 然后通过startService 来启动之
写道
本文中 这个Service 就是:WidgetUpdate

该Service 的实现如下:

Java代码 复制代码 收藏代码
  1. publicstaticclassWidgetUpdateextendsService{
  2. RemoteViewsrview;
  3. publicvoidonStart(Intentintent,intstartId){
  4. //toinitialRemoteViewsinstance
  5. rview=newRemoteViews(getPackageName(),
  6. R.layout.wlayout);
  7. }
  8. @Override
  9. publicIBinderonBind(Intentarg0){
  10. //TODOAuto-generatedmethodstub
  11. returnnull;
  12. }
  13. }
public static class WidgetUpdate extends Service {    	
    	RemoteViews rview;
    	
    	public void onStart(Intent intent, int startId) {
    		
    		//to initial RemoteViews instance
    		rview = new RemoteViews(getPackageName(),
                    R.layout.wlayout);
                    
                  

    	}
    	
 
    	
    	@Override
    	public IBinder onBind(Intent arg0) {
    		// TODO Auto-generated method stub
    		return null;
    	}
    	
}

写道
可能很多人对 RemoteView 感动奇怪 问:为什么不要findViewById()

那是因为方法:findViewById() 只在 Activity 中才可见


而 RemoteView 的作用 还是贴一下source 里面的注释把。


/**
* A class that describes a view hierarchy that can be displayed in
* another process. The hierarchy is inflated from a layout resource
* file, and this class provides some basic operations for modifying
* the content of the inflated hierarchy.
*/
public class RemoteViews implements Parcelable, Filter


注意关键字: "in another process"

4. 因为widget 肯定要接收外界的一些信息/数据 而工具就是:BroadcastReceiver 所以需要定义一个BroadcastReceiver 我们定义其为:WidgetInfoListenerHelper

Java代码 复制代码 收藏代码
  1. publicclassWidgetInfoListenerHelperextendsBroadcastReceiver{
  2. Contextcontext;
  3. WidgetInfoListenerHelperlistener;
  4. //construct
  5. publicWidgetInfoListenerHelper(Contextc){
  6. context=c;
  7. //toinstanceit
  8. listener=this;
  9. }
  10. publicvoidregisterAction(Stringaction){
  11. IntentFilterfilter=newIntentFilter();
  12. filter.addAction(action);
  13. context.registerReceiver(listener,filter);
  14. }
  15. @Override
  16. publicvoidonReceive(Contextarg0,Intentarg1){
  17. //TODOAuto-generatedmethodstub
  18. Bundleb=arg1.getExtras();
  19. if(b.containsKey(HelloHelper.MessageWidgetText)){
  20. Stringstring=b.getString(HelloHelper.MessageWidgetText);
  21. updateText(string);
  22. }
  23. }
  24. }
public class WidgetInfoListenerHelper extends BroadcastReceiver {
    		Context context;
    		
    		WidgetInfoListenerHelper listener;
    		
    		//construct 
    		public WidgetInfoListenerHelper(Context c){
    			context = c;
    			
    			//to instance it
    			listener = this;
    		}
    		
    		public void registerAction(String action){
    			IntentFilter filter = new IntentFilter();
    			filter.addAction(action);
    			
    			context.registerReceiver(listener,filter);
    		}
    		
    		@Override
    		public void onReceive(Context arg0, Intent arg1) {
    			// TODO Auto-generated method stub
    			Bundle b = arg1.getExtras();
    			
    			if(b.containsKey(HelloHelper.MessageWidgetText)){
    				String string = b.getString(HelloHelper.MessageWidgetText);
    				updateText(string);
    			}
    			

    			
    		}
    		
    	}

写道
在WidgetUpdate.onStart() 注册为:

//to register an BroadcastReceiver to listen update message
WidgetInfoListenerHelper helper = new WidgetInfoListenerHelper(this);
helper.registerAction(HelloHelper.BroadcastHelloWidget);

5. 其他:

* startActivity(Intenr)

写道
因为桌面的空间有限 所以一般只会在widget中显示一下粗略信息 当有比较多的信息时 把之放入Activity 而在widget上注册一个单击监听器 来启动目标Activity 来显示详细信息

Java代码 复制代码 收藏代码
  1. publicvoidsetViewActivityClickListener(RemoteViewsremte,intid,Intenti){
  2. PendingIntentpi=PendingIntent.getActivity(this,1,i,0);
  3. remte.setOnClickPendingIntent(id,pi);
  4. }
public void setViewActivityClickListener(RemoteViews remte,int id,Intent i){
    		
    		PendingIntent pi = PendingIntent.getActivity(this,1,i,0);
    		
    		remte.setOnClickPendingIntent(id, pi);
    	}

如何使用:

Java代码 复制代码 收藏代码
  1. setViewActivityClickListener(rview,R.id.text,
  2. newIntent(this,HelloActivity.class));
  3. 如此当点击View:R.id.text就会进入目标Activity:HelloActivity
setViewActivityClickListener(rview,R.id.text,
    				new Intent(this,HelloActivity.class));


如此 当点击View: R.id.text 就会进入目标Activity:HelloActivity

* sendBroadcast(Intent)

写道
上面有提过怎么接受Broadcast 那应该怎么发生Broadcast 呢? 也可以在View上 注册 监听器

Java代码 复制代码 收藏代码
  1. publicvoidsetViewBroadcastClickListener(RemoteViewsremte,intid,Stringfilter){
  2. Intenti=newIntent(filter);
  3. PendingIntentpi=PendingIntent.getBroadcast(this,1,i,0);
  4. remte.setOnClickPendingIntent(id,pi);
  5. }
public void setViewBroadcastClickListener(RemoteViews remte,int id,String filter){
    		Intent i = new Intent(filter);
    		
    		PendingIntent pi = PendingIntent.getBroadcast(this,1,i,0);
    		
    		remte.setOnClickPendingIntent(id, pi);
    	}

如何使用:

Java代码 复制代码 收藏代码
  1. setViewBroadcastClickListener(rview,R.id.next,HelloHelper.BroadcastDestTaskNext);
  2. 如此当点击View:R.id.next就会发生action=HelloHelper.BroadcastDestTaskNext的BroadcastReceiver
setViewBroadcastClickListener(rview,R.id.next,HelloHelper.BroadcastDestTaskNext);


如此 当点击View:R.id.next 就会发生 action=HelloHelper.BroadcastDestTaskNext 的 BroadcastReceiver

5. 最后一个问题:改动widget显示的内容, 比如:

* 改动文字:

Java代码 复制代码 收藏代码
  1. RemoteViews.setTextViewText()
RemoteViews.setTextViewText()

* 改动图片资源

Java代码 复制代码 收藏代码
  1. RemoteViews.setImageViewBitmap()
RemoteViews.setImageViewBitmap()

*

写道
补充 任何View 改动 都必须 刷新widget 才会生效 如何刷新

public void notifyViewChanged(){

// Push update for this widget to the home screen
ComponentName batteryWidget = new ComponentName(this, HelloWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(batteryWidget, rview);
}

6. emulator 运行截图:

done!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值