精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-11-26
最后修改:2010-11-26
经常看到一些教程教你如何写appwidget,但是,你知道你的appwidget是如何被添加到桌面上的吗? package chroya.demo.widget; import android.content.Context; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; /** * 承载widget的容器 * @author chroya */ public class WidgetLayout extends ViewGroup { //存放touch的坐标 private int[] cellInfo = new int[2]; private OnLongClickListener mLongClickListener; public WidgetLayout(Context context) { super(context); mLongClickListener = new OnLongClickListener() { @Override public boolean onLongClick(View v) { return false; } }; } public void addInScreen(View child, int width, int height) { LayoutParams lp = new LayoutParams(width, height); lp.x = cellInfo[0]; lp.y = cellInfo[1]; child.setOnLongClickListener(mLongClickListener); addView(child, lp); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); LayoutParams lp; for(int index=0; index<getChildCount(); index++) { lp = (LayoutParams) getChildAt(index).getLayoutParams(); getChildAt(index).measure( MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, lp.width), MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, lp.height)); } } @Override public boolean dispatchTouchEvent(MotionEvent event) { cellInfo[0] = (int)event.getX(); cellInfo[1] = (int)event.getY(); return super.dispatchTouchEvent(event); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { LayoutParams lp; for(int index=0; index<getChildCount(); index++) { lp = (LayoutParams) getChildAt(index).getLayoutParams(); getChildAt(index).layout(lp.x, lp.y, lp.x+lp.width, lp.y+lp.height); } } public static class LayoutParams extends ViewGroup.LayoutParams { int x; int y; public LayoutParams(int width, int height) { super(width, height); } } }
package chroya.demo.widget; import static android.util.Log.d; import java.util.ArrayList; import android.app.Activity; import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnLongClickListener; /** * 添加appwidget * @author chroya * */ public class Main extends Activity { private AppWidgetHost mAppWidgetHost; private AppWidgetManager mAppWidgetManager; private WidgetLayout layout; private static final int REQUEST_PICK_APPWIDGET = 1; private static final int REQUEST_CREATE_APPWIDGET = 2; private static final int APPWIDGET_HOST_ID = 0x100; private static final String EXTRA_CUSTOM_WIDGET = "custom_widget"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAppWidgetManager = AppWidgetManager.getInstance(getApplicationContext()); mAppWidgetHost = new AppWidgetHost(getApplicationContext(), APPWIDGET_HOST_ID); //开始监听widget的变化 mAppWidgetHost.startListening(); layout = new WidgetLayout(this); layout.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { addWidget(); return false; } }); setContentView(layout); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { switch (requestCode) { case REQUEST_PICK_APPWIDGET: addAppWidget(data); break; case REQUEST_CREATE_APPWIDGET: completeAddAppWidget(data); break; } } else if (requestCode == REQUEST_PICK_APPWIDGET && resultCode == RESULT_CANCELED && data != null) { // Clean up the appWidgetId if we canceled int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); if (appWidgetId != -1) { mAppWidgetHost.deleteAppWidgetId(appWidgetId); } } } /** * 选中了某个widget之后,根据是否有配置来决定直接添加还是弹出配置activity * @param data */ private void addAppWidget(Intent data) { int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); String customWidget = data.getStringExtra(EXTRA_CUSTOM_WIDGET); d("addAppWidget", "data:"+ customWidget); if ("search_widget".equals(customWidget)) { //这里直接将search_widget删掉了 mAppWidgetHost.deleteAppWidgetId(appWidgetId); } else { AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId); d("addAppWidget", "configure:"+ appWidget.configure); if (appWidget.configure != null) { //有配置,弹出配置 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); intent.setComponent(appWidget.configure); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); startActivityForResult(intent, REQUEST_CREATE_APPWIDGET); } else { //没有配置,直接添加 onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data); } } } /** * 请求添加一个新的widget */ private void addWidget() { int appWidgetId = mAppWidgetHost.allocateAppWidgetId(); Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK); pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); // add the search widget ArrayList<AppWidgetProviderInfo> customInfo = new ArrayList<AppWidgetProviderInfo>(); AppWidgetProviderInfo info = new AppWidgetProviderInfo(); info.provider = new ComponentName(getPackageName(), "XXX.YYY"); info.label = "Search"; info.icon = R.drawable.ic_search_widget; customInfo.add(info); pickIntent.putParcelableArrayListExtra( AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo); ArrayList<Bundle> customExtras = new ArrayList<Bundle>(); Bundle b = new Bundle(); b.putString(EXTRA_CUSTOM_WIDGET, "search_widget"); customExtras.add(b); pickIntent.putParcelableArrayListExtra( AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras); // start the pick activity startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET); } /** * 添加widget * @param data */ private void completeAddAppWidget(Intent data) { Bundle extras = data.getExtras(); int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); d("completeAddAppWidget", "dumping extras content="+extras.toString()); d("completeAddAppWidget", "appWidgetId:"+ appWidgetId); AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId); View hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo); layout.addInScreen(hostView, appWidgetInfo.minWidth, appWidgetInfo.minHeight); } }
运行效果如下:
源码见附件。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-12-01
我就喜欢带例子的
|
|
返回顶楼 | |
发表时间:2010-12-02
LZ 我看过你写的一个事件机制
但是有一点我遇到了一个问题。 就是子View 和父View 事件重复问题。 具体的就是 ScrollView 里面有一个TextView TextView 有一个OnTouchListener 我做的功能是 让这个TextView 可以拖动,但是拖动的时候触发了 ScrollView 的事件 导致 TextView 移动不成功(动几下就停了) 请问 这种怎么解决? 怎么在子View 里面屏蔽/拦截掉父View的事件? |
|
返回顶楼 | |
发表时间:2010-12-02
aa87963014 写道 LZ 我看过你写的一个事件机制
但是有一点我遇到了一个问题。 就是子View 和父View 事件重复问题。 具体的就是 ScrollView 里面有一个TextView TextView 有一个OnTouchListener 我做的功能是 让这个TextView 可以拖动,但是拖动的时候触发了 ScrollView 的事件 导致 TextView 移动不成功(动几下就停了) 请问 这种怎么解决? 怎么在子View 里面屏蔽/拦截掉父View的事件? TextView 的OnTouchListener里面onTouch返回值设为true。ScrollView也setOnTouchListener,返回false。 |
|
返回顶楼 | |
发表时间:2010-12-20
好东西,呵呵,暂时用不到,收藏Le,谢谢
|
|
返回顶楼 | |
发表时间:2011-02-09
LZ你有没有出现过
StackTrace=bitmap size exceeds VM budgetjava.lang.OutOfMemoryError: bitmap size exceeds VM budget at android.graphics.Bitmap.nativeCreateFromParcel(Native Method) at android.graphics.Bitmap.access$000(Bitmap.java:29) at android.graphics.Bitmap$1.createFromParcel(Bitmap.java:927) at android.graphics.Bitmap$1.createFromParcel(Bitmap.java:933) at android.widget.RemoteViews$ReflectionAction.<init>(RemoteViews.java:344) at android.widget.RemoteViews.<init>(RemoteViews.java:559) at android.widget.RemoteViews$1.createFromParcel(RemoteViews.java:1012) at android.widget.RemoteViews$1.createFromParcel(RemoteViews.java:1015) at com.android.internal.appwidget.IAppWidgetHost$Stub.onTransact(IAppWidgetHost.java:53) at android.os.Binder.execTransact(Binder.java:304) at dalvik.system.NativeStart.run(Native Method) |
|
返回顶楼 | |
发表时间:2011-02-10
liyh.vip 写道 LZ你有没有出现过
StackTrace=bitmap size exceeds VM budgetjava.lang.OutOfMemoryError: bitmap size exceeds VM budget at android.graphics.Bitmap.nativeCreateFromParcel(Native Method) at android.graphics.Bitmap.access$000(Bitmap.java:29) at android.graphics.Bitmap$1.createFromParcel(Bitmap.java:927) at android.graphics.Bitmap$1.createFromParcel(Bitmap.java:933) at android.widget.RemoteViews$ReflectionAction.<init>(RemoteViews.java:344) at android.widget.RemoteViews.<init>(RemoteViews.java:559) at android.widget.RemoteViews$1.createFromParcel(RemoteViews.java:1012) at android.widget.RemoteViews$1.createFromParcel(RemoteViews.java:1015) at com.android.internal.appwidget.IAppWidgetHost$Stub.onTransact(IAppWidgetHost.java:53) at android.os.Binder.execTransact(Binder.java:304) at dalvik.system.NativeStart.run(Native Method) 这样的情况一般出现在大分辨率的机子上,图片占用的内存过大而导致的。暂时没有很完美的解决办法,但是还是能用一些方法来避免,网上可以搜到的。 |
|
返回顶楼 | |
浏览 12554 次