简体   繁体   English

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

[英]What's the proper way to implement an Android widget with dynamically drawn content?

For my first and most awesomest Android project, I want to create a home screen widget which displays one of those Arc Clocks that all the kids are raving about these days.对于我的第一个也是最棒的 Android 项目,我想创建一个主屏幕小部件,它显示这些天所有孩子都热衷的Arc Clocks之一。

Based on the limitations of RemoteViews , it looks to me that the appropriate way to get it actually drawn on the screen is to use an ImageView in the actual layout, then when it is updating, create a ShapeDrawable or two and draw them onto a newly created Bitmap .基于RemoteViews的局限性,在我看来,在屏幕上实际绘制它的适当方法是在实际布局中使用ImageView ,然后在更新时,创建一个或两个ShapeDrawable并将它们绘制到新的创建位图 Then, set that Bitmap as the source of the ImageView.然后,将该位图设置为 ImageView 的源。

There is Something about that process that I'm just not grokking, though.不过,我并没有对此过程感到困惑。 The following is the code I tried to use to update the widget.以下是我尝试用来更新小部件的代码。 I get nothing drawn on the screen at all.我根本没有在屏幕上绘制任何内容。 The ImageView has a placeholder image just set by its src property. ImageView 有一个仅由其src属性设置的占位符图像。 When I don't run the code to update it to my drawing, the placeholder image stays in place.当我不运行代码将其更新为我的绘图时,占位符图像将保持原位。 So, I know this code is doing something , just obviously not the right thing.所以,我知道这段代码正在做一些事情,显然不是正确的事情。

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);

I knew it couldn't be that easy.我知道这不可能那么容易。 So, am I even heading in the right direction?那么,我是否朝着正确的方向前进?


Update更新

Ok, maybe that was too much information.好吧,也许信息太多了。 The question I'm really trying to ask is this:我真正想问的问题是:

If I want to draw shapes on a widget, should I use an ImageView and create a bitmap from my ShapeDrawable or is there more appropriate way to draw into a widget where it is constrained by RemoteViews?如果我想在小部件上绘制形状,我应该使用 ImageView 并从我的 ShapeDrawable 创建位图还是有更合适的方法来绘制到受 RemoteViews 约束的小部件?

There is actually a widget called AnalogClock in the SDK that is very similar to what you are trying to do. SDK 中实际上有一个名为AnalogClock的小部件,它与您尝试执行的操作非常相似。

It is implemented as a class that extends View and is annotated with @RemoteView .它被实现为一个扩展View的类,并使用@RemoteView注释。 It registers receivers on Intent.ACTION_TIME_TICK and Intent.ACTION_TIME_CHANGED and draws itself by overriding the onDraw method.它在Intent.ACTION_TIME_TICKIntent.ACTION_TIME_CHANGED上注册接收器,并通过覆盖onDraw方法绘制自己。 Check out the source .查看源代码 The standard AlarmClock application exposes this view as a widget that can be added to the home screen.标准的AlarmClock应用程序将此视图公开为可以添加到主屏幕的小部件。

I think that is a good (if not the best) way to implement what you described and obviously works well.我认为这是实现您所描述的内容的好方法(如果不是最好的)并且显然效果很好。

This works great:这很好用:

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);

I guess the problem with your original code was just the way of drawing the arc - that's why nothing showed up.我想你的原始代码的问题只是绘制弧线的方式 - 这就是为什么什么都没有出现的原因。

BTW: You can find a customizable "Arc Clock" with a very small memory footprint in the Market by searching for "arc clock"!顺便说一句:您可以通过搜索“弧形时钟”在市场中找到一个内存占用非常小的可定制“弧形时钟”!

To create an custom component, I would extend View or any subclass of View and override the onDraw(Canvas canvas) method to do your drawing.要创建自定义组件,我将扩展 View 或 View 的任何子类并覆盖 onDraw(Canvas canvas) 方法来进行绘图。 On the the canvas object you can call methods such as drawLine(), drawArc(), drawPicture(), drawPoints(), drawText(), drawRect(), etc.....在画布对象上可以调用drawLine()、drawArc()、drawPicture()、drawPoints()、drawText()、drawRect()等方法......

Here's more details. 这里有更多细节。

Here's the api for canvas. 这是画布的api。

I believe you can then add your custom view to a remote view for the purpose of making a widget.我相信您可以将自定义视图添加到远程视图中,以便制作小部件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Android 上实现可恢复调度程序的正确方法是什么? - What's the proper way to implement resumable scheduler on Android? 初始化 Android 应用程序的正确方法是什么? - What's the proper way to initialize an Android application? 设置Android PreferenceFragment的正确方法是什么? - What's the proper way to setup an Android PreferenceFragment? 什么是在MvvmCross 3.5.1中实现Fragments的正确方法 - What's the proper way to implement Fragments in MvvmCross 3.5.1 实现 SharedPreferencesBackupHelper 的正确方法是什么? - What is the proper way to implement SharedPreferencesBackupHelper? 在android中实现服务的正确方法 - Proper way to implement services in android Android:如果ListView中的项目内容是动态的,实现BaseAdapter的最佳方法是什么? - Android: What’s the best way to implement the BaseAdapter if item content in ListView is dynamic? 在颤振中为小部件设置动画的正确方法是什么 - What is The proper way to animate a widget in flutter 在Android中实现双向列表视图的正确方法 - Proper way to implement a two way listview in android 将选项列表导入Android应用的正确方法是什么? - What's the proper way of importing option lists into an Android app?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM