经常看到一些教程教你如何写appwidget,但是,你知道你的appwidget是如何被添加到桌面上的吗?
一般的,如果是做桌面的童鞋,基本上都会让自己的桌面支持appwidget。下面说说如何实现。
首先是得定义一个承载appwidget的容器,系统的Launcher里面是用的CellLayout,实现的很不错。我这里就用一个简单的自定义ViewGroup来搞定,它是以长按的坐标处为要添加的appwidget的起始位置,简单点说就是按到哪儿就添加到哪儿.
1.package chroya.demo.widget;
2.
3.import android.content.Context;
4.import android.view.MotionEvent;
5.import android.view.View;
6.import android.view.ViewGroup;
7.
8./**
9. * 承载widget的容器
10. * @author chroya
11. */
12.public class WidgetLayout extends ViewGroup {
13. //存放touch的坐标
14. private int [] cellInfo = new int [ 2 ];
15. private OnLongClickListener mLongClickListener;
16.
17. public WidgetLayout(Context context) {
18. super (context);
19. mLongClickListener = new OnLongClickListener() {
20.
21. @Override
22. public boolean onLongClick(View v) {
23.
24. return false ;
25. }
26. };
27. }
28.
29. public void addInScreen(View child, int width, int height) {
30. LayoutParams lp = new LayoutParams(width, height);
31. lp.x = cellInfo[0 ];
32. lp.y = cellInfo[1 ];
33. child.setOnLongClickListener(mLongClickListener);
34. addView(child, lp);
35. }
36.
37. @Override
38. protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec) {
39. super .onMeasure(widthMeasureSpec, heightMeasureSpec);
40. LayoutParams lp;
41. for ( int index= 0 ; index<getChildCount(); index++) {
42. lp = (LayoutParams) getChildAt(index).getLayoutParams();
43. getChildAt(index).measure(
44. MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, lp.width),
45. MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, lp.height));
46. }
47. }
48.
49. @Override
50. public boolean dispatchTouchEvent(MotionEvent event) {
51. cellInfo[0 ] = ( int )event.getX();
52. cellInfo[1 ] = ( int )event.getY();
53. return super .dispatchTouchEvent(event);
54. }
55.
56. @Override
57. protected void onLayout( boolean changed, int l, int t, int r, int b) {
58. LayoutParams lp;
59. for ( int index= 0 ; index<getChildCount(); index++) {
60. lp = (LayoutParams) getChildAt(index).getLayoutParams();
61. getChildAt(index).layout(lp.x, lp.y, lp.x+lp.width, lp.y+lp.height);
62. }
63. }
64.
65. public static class LayoutParams extends ViewGroup.LayoutParams {
66. int x;
67. int y;
68.
69. public LayoutParams( int width, int height) {
70. super (width, height);
71. }
72. }
73.}
然后是重点了。还记得系统默认的桌面上,长按的时候出现的上下文菜单吗?里面有好几个选项,选择widget之后,会弹出一个已经安装的widget列表,选择一个widget之后,就会添加到桌面。我们可以把第一步去掉,长按之后,直接弹出已安装的widget列表,这是一个activity,用AppWidgetManager.ACTION_APPWIDGET_PICK这个Intent来启动,必须带上Extras,下面给出代码中有,不详叙。
1.package chroya.demo.widget;
2.
3.import static android.util.Log.d;
4.
5.import java.util.ArrayList;
6.
7.import android.app.Activity;
8.import android.appwidget.AppWidgetHost;
9.import android.appwidget.AppWidgetManager;
10.import android.appwidget.AppWidgetProviderInfo;
11.import android.content.ComponentName;
12.import android.content.Intent;
13.import android.os.Bundle;
14.import android.view.View;
15.import android.view.View.OnLongClickListener;
16.
17./**
18. * 添加appwidget
19. * @author chroya
20. *
21. */
22.public class Main extends Activity {
23. private AppWidgetHost mAppWidgetHost;
24. private AppWidgetManager mAppWidgetManager;
25. private WidgetLayout layout;
26.
27. private static final int REQUEST_PICK_APPWIDGET = 1 ;
28. private static final int REQUEST_CREATE_APPWIDGET = 2 ;
29. private static final int APPWIDGET_HOST_ID = 0x100 ;
30. private static final String EXTRA_CUSTOM_WIDGET = "custom_widget" ;
31.
32. @Override
33. public void onCreate(Bundle savedInstanceState) {
34. super .onCreate(savedInstanceState);
35.
36. mAppWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
37. mAppWidgetHost = new AppWidgetHost(getApplicationContext(), APPWIDGET_HOST_ID);
38. //开始监听widget的变化
39. mAppWidgetHost.startListening();
40.
41. layout = new WidgetLayout( this );
42. layout.setOnLongClickListener(new OnLongClickListener() {
43.
44. @Override
45. public boolean onLongClick(View v) {
46.
47. addWidget();
48. return false ;
49. }
50. });
51. setContentView(layout);
52. }
53.
54. @Override
55. protected void onActivityResult( int requestCode, int resultCode, Intent data) {
56. if (resultCode == RESULT_OK) {
57. switch (requestCode) {
58. case REQUEST_PICK_APPWIDGET:
59. addAppWidget(data);
60. break ;
61. case REQUEST_CREATE_APPWIDGET:
62. completeAddAppWidget(data);
63. break ;
64. }
65. } else if (requestCode == REQUEST_PICK_APPWIDGET &&
66. resultCode == RESULT_CANCELED && data != null ) {
67. // Clean up the appWidgetId if we canceled
68. int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, - 1 );
69. if (appWidgetId != - 1 ) {
70. mAppWidgetHost.deleteAppWidgetId(appWidgetId);
71. }
72. }
73. }
74.
75. /**
76. * 选中了某个widget之后,根据是否有配置来决定直接添加还是弹出配置activity
77. * @param data
78. */
79. private void addAppWidget(Intent data) {
80. int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, - 1 );
81.
82. String customWidget = data.getStringExtra(EXTRA_CUSTOM_WIDGET);
83. d("addAppWidget" , "data:" + customWidget);
84. if ( "search_widget" .equals(customWidget)) {
85. //这里直接将search_widget删掉了
86. mAppWidgetHost.deleteAppWidgetId(appWidgetId);
87. } else {
88. AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
89.
90. d("addAppWidget" , "configure:" + appWidget.configure);
91. if (appWidget.configure != null ) {
92. //有配置,弹出配置
93. Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
94. intent.setComponent(appWidget.configure);
95. intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
96.
97. startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
98. } else {
99. //没有配置,直接添加
100. onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);
101. }
102. }
103. }
104.
105. /**
106. * 请求添加一个新的widget
107. */
108. private void addWidget() {
109. int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
110.
111. Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
112. pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
113. // add the search widget
114. ArrayList<AppWidgetProviderInfo> customInfo =
115. new ArrayList<AppWidgetProviderInfo>();
116. AppWidgetProviderInfo info = new AppWidgetProviderInfo();
117. info.provider = new ComponentName(getPackageName(), "XXX.YYY" );
118. info.label = "Search" ;
119. info.icon = R.drawable.ic_search_widget;
120. customInfo.add(info);
121. pickIntent.putParcelableArrayListExtra(
122. AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);
123. ArrayList<Bundle> customExtras = new ArrayList<Bundle>();
124. Bundle b = new Bundle();
125. b.putString(EXTRA_CUSTOM_WIDGET, "search_widget" );
126. customExtras.add(b);
127. pickIntent.putParcelableArrayListExtra(
128. AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);
129. // start the pick activity
130. startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
131. }
132.
133. /**
134. * 添加widget
135. * @param data
136. */
137. private void completeAddAppWidget(Intent data) {
138. Bundle extras = data.getExtras();
139. int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, - 1 );
140.
141. d("completeAddAppWidget" , "dumping extras content=" +extras.toString());
142. d("completeAddAppWidget" , "appWidgetId:" + appWidgetId);
143. AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
144.
145. View hostView = mAppWidgetHost.createView(this , appWidgetId, appWidgetInfo);
146.
147. layout.addInScreen(hostView, appWidgetInfo.minWidth, appWidgetInfo.minHeight);
148. }
149.}
需要注意的几点:
1。 必须调用AppWidgetHost的startListening方法来监听appwidget的状态变化,否则添加上去的appwidget不会更新的。
2。 需要override一个onActivityResult方法,来接收添加appwidget和appwidget的配置activity的返回值。
3。 启动AppWidgetManager.ACTION_APPWIDGET_PICK这个Intent,必须要给列表中加上自己定义的一个选项,否则出错。如本例中是用的Search。
分享到:
相关推荐
Android 桌面控件(AppWidget)是Android操作系统提供的一种独特功能,允许开发者创建可以在用户主屏幕上显示的小型应用程序组件。这些控件通常提供快速访问应用的核心功能或展示实时信息,如天气预报、日历事件或...
在Android开发中,AppWidget是桌面小部件,它允许用户在主屏幕上与应用程序进行交互,而无需实际打开应用。在本篇博文中,我们将深入探讨如何在AppWidget中启动一个新的Activity,这通常是为了提供更丰富的用户体验...
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> android:name="android.appwidget.provider" android:resource="@xml/app_widget_info" /> ``` 其中,`<meta-data>` 标签引用了一个 ...
9. **服务(Service)与AppWidget**: 在某些情况下,你可能需要使用服务来支持AppWidget的后台任务,例如定时更新。Service可以用来处理这些长时间运行的任务,同时保持小部件的更新。 10. **兼容性与版本差异**: ...
**Android之AppWidget详解** AppWidget是Android操作系统提供的一种组件,允许开发者在用户主屏幕上创建小型应用程序,这些小部件...通过理解和熟练运用AppWidget,开发者可以构建出更加丰富和个性化的Android应用。
在Android系统中,AppWidget是桌面小部件的实现方式,它允许开发者将应用程序的功能和信息直接集成到用户的主屏幕上,用户无需打开应用就能与之交互。AppWidget虽然看似简单,但其实涉及到了许多核心的Android组件和...
这个压缩包“Android小部件AppWidget.rar”似乎包含了一些关于创建和实现Android Widget小组件的资源,可能是源代码、文档或者示例项目。 在Android开发中,AppWidget是Widget小组件的主要实现类。它是由Android ...
在这个名为"AppWidget-master"的压缩包中,我们很可能是得到了一个示例项目,用于演示如何创建一个能够显示列表并支持刷新功能的Android App Widget。 首先,我们需要理解App Widget的基本架构。App Widget由XML...
创建一个新的Android项目,确保目标API版本支持AppWidget功能。在`AndroidManifest.xml`中声明AppWidget提供者,例如: ```xml <receiver android:name=".AppWidgetProvider"> <action android:name="android....
通过深入学习和实践这个源码示例,你将能够掌握AppWidget的开发流程,为自己的Android应用添加更多元化的交互方式,提升用户体验。同时,这也为你进一步探索Android系统的广播机制、服务、ContentProvider等高级特性...
在Android开发中,AppWidget是桌面小部件,可以让用户在主屏幕上放置应用程序的轻量级交互界面。在Android 4.0(API级别14)及以上版本,开发者可以创建AppWidget集合,展示一系列数据,例如列表或网格形式的条目。...
在Android平台上,Widget小组件是应用在主屏幕上提供快速访问或简单交互的一种方式。它们可以显示实时信息,比如天气、时钟或者新闻摘要,而无需用户打开完整的应用程序。本资料包"androidWidget小组件开发.zip"包含...
总的来说,Android AppWidget控件为开发者提供了扩展主屏幕功能的能力,通过简单的布局设计和广播机制,可以让用户在不打开应用程序的情况下与应用进行交互。这种交互方式不仅提升了用户体验,也使得应用程序更加...
在Android开发中,AppWidget是桌面小部件,它允许用户在主屏幕上添加应用程序的功能,而无需实际打开应用程序。本文将深入探讨如何实现Android AppWidget的高级效果,以一个掷骰子的Widget为例。 首先,创建App...
在Android平台上,开发者可以利用Android桌面小部件(Widget)功能为用户提供便捷的桌面服务,比如...通过这样的项目实践,开发者能够提升自己的Android应用开发技能,并为用户提供富有创意和实用性的桌面体验。
总之,"android 源码 android Widget开发案例 eclipse项目 直接导入"为开发者提供了一个实践平台,通过它,开发者能够深入学习Widget的工作原理,提高Android应用的桌面体验设计能力,让手机界面更加个性化和实用。
在Android系统中,小部件(AppWidget)是用户可以在主屏幕上添加的应用程序组件,它们提供了一种无需打开应用即可与应用交互的方式。本资源“安卓Andriod源码——小部件AppWidget.zip”包含了关于创建和实现Android...
AppWidget是Android系统中的一个特性,它让用户能够在主屏幕上放置应用程序的部分界面,提供快速访问和操作的功能。创建AppWidget需要实现一系列组件,如`AppWidgetProvider`(类似广播接收器的组件,响应特定事件)...
在Android开发中,App Widget是一种轻量级的应用组件,它可以被添加到用户的桌面或其它支持App Widget的应用中,为用户提供快速访问或操作的功能。App Widget虽然不像完整的应用程序那样拥有丰富的交互,但它们可以...