使用动态绘制的内容实现Android小部件的正确方法是什么?

时间:2010-02-02 02:46:57

标签: android android-widget

对于我的第一个也是最棒的Android项目,我想创建一个主屏幕小部件,其中显示了所有孩子们最近都在讨论的Arc Clocks之一。

基于RemoteViews的限制,我认为在屏幕上实际绘制它的恰当方法是在实际布局中使用ImageView,然后在更新时,创建一个或两个ShapeDrawable并将它们绘制到新创建的Bitmap上。然后,将Bitmap设置为ImageView的源。

但是有一些关于这个过程的东西,我只是不喜欢。以下是我尝试用来更新小部件的代码。我根本没有在屏幕上画任何东西。 ImageView具有仅由其src属性设置的占位符图像。当我不运行代码将其更新到我的绘图时,占位符图像保持不变。所以,我知道这段代码正在做某些事情,显然不是正确的事情。

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);

ShapeDrawable drawable = new ShapeDrawable(new ArcShape(0, 360));
drawable.getPaint().setColor(0xffff0000);
drawable.getPaint().setStrokeWidth(5.0f);
drawable.setIntrinsicWidth(100);
drawable.setIntrinsicHeight(100);
drawable.draw(canvas);

views.setImageViewBitmap(R.id.ImageView01, bitmap);     
appWidgetManager.updateAppWidget(appWidgetId, views);

我知道这不容易。那么,我是否正朝着正确的方向前进?


更新

好吧,也许那是太多的信息。我真正想问的问题是:

如果我想在窗口小部件上绘制形状,我应该使用ImageView并从我的ShapeDrawable创建一个位图,还是有更合适的方法来绘制一个受RemoteView约束的窗口小部件?

3 个答案:

答案 0 :(得分:8)

SDK中实际上有一个名为AnalogClock的小部件,与您尝试的内容非常相似。

它实现为扩展View的类,并使用@RemoteView进行注释。它在Intent.ACTION_TIME_TICKIntent.ACTION_TIME_CHANGED上注册接收器,并通过覆盖onDraw方法来绘制自己。查看source。标准AlarmClock应用exposes this view作为可添加到主屏幕的小部件。

我认为这是一种很好的(如果不是最好的)方式来实现你所描述的并且显然效果很好。

答案 1 :(得分:5)

这很有效:

Paint p = new Paint(); 
p.setAntiAlias(true);
p.setStyle(Style.STROKE);
p.setStrokeWidth(8);
p.setColor(0xFFFF0000);

Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawArc(new RectF(10, 10, 90, 90), 0, 270, false, p);

RemoteViews views = new RemoteViews(updateService.getPackageName(), R.layout.main);
views.setImageViewBitmap(R.id.canvas, bitmap);

ComponentName componentName = new ComponentName(updateService, DashboardAppWidgetProvider.class);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(updateService);
appWidgetManager.updateAppWidget(componentName, views);

我想原始代码的问题只是绘制弧线的方式 - 这就是为什么没有出现的原因。

顺便说一句:你可以通过搜索“弧形时钟”在市场上找到一个可定制的“弧形时钟”,占用的内存非常小!

答案 2 :(得分:0)

要创建自定义组件,我会扩展View或View的任何子类,并覆盖onDraw(Canvas画布)方法来进行绘制。在canvas对象上,你可以调用drawLine(),drawArc(),drawPicture(),drawPoints(),drawText(),drawRect()等方法......

Here's more details.

Here's the api for canvas.

我相信您可以将自定义视图添加到远程视图以制作小部件。