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.

The rest of this section considers a single application, much like the one used in Example 12-6: a couple of LinearLayouts that contain multiple instances of a single widget, each demonstrating a different graphics effect. Example 12-10 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 12-10. Effects widget public class EffectsWidget extends View {

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(l0, 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);



canvas.drawRect(canvas.getClipBounds(), paint);

The application that uses this widget, shown in Example 12-11, 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 12-11. Effects application private void buildView() {


LinearLayout view = (LinearLayout) findViewById(; view.addView(new EffectsWidget( this, 1, new EffectsWidget.PaintEffect() {

^Override public void setEffect(Paint paint) { paint.setShadowLayer(l, 3, 4, Color.BLUE); } }));

view.addView(new EffectsWidget( this, 3, new EffectsWidget.PaintEffect() {

^Override public void setEffect(Paint paint) {


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 = (LinearLayout) findViewById(; 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,


// A widget with an animated background View w = new EffectsWidget( this, 6, new EffectsWidget.PaintEffect() {

@Override public void setEffect(Paint paint) { }



// This is, alas, necessary until Cupcake. w.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) {

((AnimationDrawable) v.getBackground()).start(); } });

Figure 12-5 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.

Stroke Android Drawrect Gradient

Figure 12-5. Graphics effects

0 0

Post a comment