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

Moj*_*ter 14 android android-widget

对于我的第一个也是最令人敬畏的Android项目,我想创建一个主屏幕小部件,其中显示了所有孩子们最近都在讨论的其中一个弧形时钟.

基于RemoteViews的限制,我认为在屏幕上实际绘制它的合适方法是在实际布局中使用ImageView,然后在更新时,创建一个或两个ShapeDrawable并将它们绘制到一个新的创建了位图.然后,将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);
Run Code Online (Sandbox Code Playgroud)

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


更新

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

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

Jos*_*ger 8

实际上AnalogClock,SDK中调用的小部件与您尝试执行的操作非常相似.

它被实现为一个扩展View和注释的类@RemoteView.它注册在接收器Intent.ACTION_TIME_TICKIntent.ACTION_TIME_CHANGED并通过重写绘制本身onDraw方法.查看来源.标准AlarmClock应用程序将此视图公开 为可添加到主屏幕的窗口小部件.

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

  • 但是你知道如何使用@RemoteView创建custon View descedant吗?我尝试创建自己的一个,但小部件在加载时崩溃. (2认同)

Cra*_*ris 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);
Run Code Online (Sandbox Code Playgroud)

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

顺便说一句:你可以通过搜索"弧形时钟"找到市场上占用空间非常小的可定制"弧形时钟"!