The Android UI framework is a lot more
than a just an intelligent, well-put-together GUI toolkit. When it takes
off its glasses and shakes out its hair, it can be downright sexy! The
tools mentioned here certainly do not make an exhaustive catalog. They
might get you started, though, on the path to making your application
Filthy Rich. Several of the techniques discussed in this section are close to
the edges of the Android landscape. As such, they are less well
established: the documentation is not as thorough, some of the features
are clearly in transition, and you may even find bugs. If you run into
problems, the Google Group “Android Developers” is an invaluable
resource. Questions about a particular aspect of the toolkit have
sometimes been answered by the very person responsible for implementing
that aspect. Be careful about checking the dates on solutions you find by
searching the Web. Some of these features are changing rapidly, and code
that worked as recently as six months ago may not work now. A corollary,
of course, is that any application that gets wide distribution is likely
to be run on platforms that have differing implementations of the
features discussed here. By using these techniques, you may limit the
lifetime of your application and the number of devices that it will
support. |
|
Example 1 contains the key parts of the
widget, with code discussed previously elided for brevity. The widget
simply draws a few graphical objects and defines an interface through
which various graphics effects can be applied to the rendering. Example 1. Effects widgetpublic class EffectsWidget extends View {
/** The effect to apply to the drawing */ public interface PaintEffect { void setEffect(Paint paint); }
// ...
// PaintWidget's widget rendering method protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setAntiAlias(true);
effect.setEffect(paint); paint.setColor(Color.DKGRAY);
paint.setStrokeWidth(5); canvas.drawLine(10, 10, 140, 20, paint);
paint.setTextSize(26); canvas.drawText("Android", 40, 50, paint);
paint = new Paint(); paint.setColor(Color.BLACK); canvas.drawText(String.valueOf(id), 2.0F, 12.0F, paint); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); canvas.drawRect(canvas.getClipBounds(), paint); } }
|
The application that uses this widget, shown in Example 2, should also feel familiar. It
creates several copies of the EffectsWidget, each with its own effect. There
are two special widgets: the bottom widget in the right column is
animated, and the bottom widget in the left column uses OpenGL
animation. Example 2. Effects applicationprivate void buildView() { setContentView(R.layout.main);
LinearLayout view = (LinearLayout) findViewById(R.id.v_left); view.addView(new EffectsWidget( this, 1, new EffectsWidget.PaintEffect() { @Override public void setEffect(Paint paint) { paint.setShadowLayer(1, 3, 4, Color.BLUE); } })); view.addView(new EffectsWidget( this, 3, new EffectsWidget.PaintEffect() { @Override public void setEffect(Paint paint) { paint.setShader( new LinearGradient( 0.0F, 0.0F, 160.0F, 80.0F, new int[] { Color.BLACK, Color.RED, Color.YELLOW }, new float[] { 0.2F, 0.3F, 0.2F }, Shader.TileMode.REPEAT)); } })); view.addView(new EffectsWidget( this, 5, new EffectsWidget.PaintEffect() { @Override public void setEffect(Paint paint) { paint.setMaskFilter( new BlurMaskFilter(2, BlurMaskFilter.Blur.NORMAL)); } }));
// Not and EffectsWidget: this is the OpenGL Anamation widget. glWidget = new GLDemoWidget(this); view.addView(glWidget);
view = (LinearLayout) findViewById(R.id.v_right); view.addView(new EffectsWidget( this, 2, new EffectsWidget.PaintEffect() { @Override public void setEffect(Paint paint) { paint.setShadowLayer(3, -8, 7, Color.GREEN); } })); view.addView(new EffectsWidget( this, 4, new EffectsWidget.PaintEffect() { @Override public void setEffect(Paint paint) { paint.setShader( new LinearGradient( 0.0F, 40.0F, 15.0F, 40.0F, Color.BLUE, Color.GREEN, Shader.TileMode.MIRROR)); } }));
// A widget with an animated background View w = new EffectsWidget( this, 6, new EffectsWidget.PaintEffect() { @Override public void setEffect(Paint paint) { } }); view.addView(w); w.setBackgroundResource(R.drawable.throbber);
// This is, alas, necessary until Cupcake. w.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { ((AnimationDrawable) v.getBackground()).start(); } }); }
|
Figure 1 shows what the
code looks like when run. The bottom two widgets are animated: the green
checkerboard moves from left to right across the widget, and the
bottom-right widget has a throbbing red background.
|