2010-02-02 19 views
13

Para mi primer y más asombroso proyecto de Android, quiero crear un widget de pantalla de inicio que muestra uno de esos Arc Clocks que todos los niños están delirando en estos días.¿Cuál es la manera correcta de implementar un widget de Android con contenido dibujado dinámicamente?

Sobre la base de las limitaciones de RemoteViews, parece a mí que la forma adecuada para conseguir que realmente dibuja en la pantalla es utilizar un ImageView en la disposición real, a continuación, cuando se está poniendo al día, crear un ShapeDrawable o dos y dibujar en un recién creado . Luego, configure ese mapa de bits como fuente de ImageView.

Sin embargo, hay algo acerca de ese proceso en el que no estoy creciendo. El siguiente es el código que traté de usar para actualizar el widget. No obtengo nada dibujado en la pantalla. ImageView tiene una imagen de marcador de posición simplemente establecida por su propiedad src. Cuando no ejecuto el código para actualizarlo a mi dibujo, la imagen del marcador de posición permanece en su lugar. Por lo tanto, sé que este código está haciendo algo, obviamente no es el lo correcto cosa.

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

Sabía que no podía ser tan fácil. Entonces, ¿estoy yendo en la dirección correcta?


actualización

Ok, tal vez era demasiada información. La pregunta que realmente estoy tratando de hacer es la siguiente:

Si quiero dibujar formas en un widget, ¿debo usar un ImageView y crear un mapa de bits de ShapeDrawable o hay una forma más apropiada de dibujar en un widget donde está limitado por RemoteViews?

+0

¿Estás diciendo que el marcador de posición todavía está allí cuando intentas dibujar algo sobre él? – sandos

+0

No, la imagen del marcador de posición desaparece. Termina con nada visual en la pantalla. Sin embargo, puedo mantener presionada la tecla y eliminar el widget. – MojoFilter

Respuesta

8

En realidad, hay un widget llamado AnalogClock en el SDK que es muy similar a lo que está intentando hacer.

Se implementa como una clase que se extiende View y está anotado con @RemoteView. Registra los receptores en Intent.ACTION_TIME_TICK y Intent.ACTION_TIME_CHANGED y se dibuja sobrescribiendo el método onDraw. Consulte el source. La aplicación estándar AlarmClockexposesthisview como un widget que se puede agregar a la pantalla de inicio.

Creo que es una buena (si no la mejor) forma de implementar lo que describiste y obviamente funciona bien.

+0

Oh, genial. Tenía la impresión de que no podía extender una vista y agregarla a una vista remota porque solo se permitían tipos muy específicos en una vista remota, incluso subclases. Si eso es todo lo que se necesita, entonces creo que debería ser capaz de rock and roll. Lo intentaré. – MojoFilter

+0

Esta es la documentación que me dio esa impresión: http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout – MojoFilter

+0

Lo probé y desafortunadamente no se puede ver la subclase y agregarlo a un diseño utilizado en una vista remota, por lo que yo sé. La única razón por la que funciona para la vista de AnalogClock es que AnalogClock es uno de esos componentes explícitamente permitidos. – MojoFilter

0

Para crear un componente personalizado, extendería View o cualquier subclase de View y anularía el método onDraw (Canvas canvas) para hacer su dibujo. En el objeto de la tela puede llamar a métodos como drawLine(), drawArc(), DrawPicture(), drawPoints(), drawText(), drawRect(), etc .....

Here's more details.

Here's the api for canvas.

Creo que puede agregar su vista personalizada a una vista remota con el fin de hacer un widget.

+0

Estoy bastante seguro de que ese es todo el problema. Si pudiera subclasificar una vista, sería realmente simple. Sin embargo, las RemoteViews que usa para hablar con un widget solo pueden contener un conjunto muy específico de elementos. – MojoFilter

5

Esto funciona muy bien:

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

supongo que el problema con el código original de la manera de extraer el arco - por eso no se presentó.

BTW: ¡Usted puede encontrar un "reloj de arco" personalizable con una huella de memoria muy pequeña en el mercado buscando "reloj de arco"!

Cuestiones relacionadas