[Tut] Stateful CustomImageButton with programatic Draw

Tutorials with advanced 'difficulty' and more Lines of Code.

[Tut] Stateful CustomImageButton with programatic Draw

Postby mauri » Thu Feb 14, 2008 5:40 pm

Hi all

since the new SDK i'm not so happy with the buttons (grey instead of black in the Dark Theme). So decided to draw my own Buttons.

The are centenly more then one way to do this.
My goal is to draw the Image programticly, instead of producing bitmaps with a paint-programm.
Here's my way...

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package org.anddev;
  3.  
  4.  
  5.  
  6. import android.app.Activity;
  7.  
  8. import android.content.Context;
  9.  
  10. import android.graphics.Bitmap;
  11.  
  12. import android.graphics.Canvas;
  13.  
  14. import android.graphics.Paint;
  15.  
  16. import android.graphics.Path;
  17.  
  18. import android.graphics.RectF;
  19.  
  20. import android.graphics.Paint.Style;
  21.  
  22. import android.graphics.Path.Direction;
  23.  
  24. import android.os.Bundle;
  25.  
  26. import android.view.View;
  27.  
  28. import android.widget.Button;
  29.  
  30. import android.widget.LinearLayout;
  31.  
  32. import android.widget.TextView;
  33.  
  34. import android.widget.LinearLayout.LayoutParams;
  35.  
  36. /*
  37.  
  38.  * Sample CustomImageButton
  39.  
  40.  * Programatic draw a own Button, whit different States
  41.  
  42.  * default, focused and pressed
  43.  
  44.  *
  45.  
  46.  *  14.02.2008 by Mauri for anddev.org
  47.  
  48.  */
  49.  
  50. public class CustomImageButton extends Activity {
  51.  
  52.     private TextView mDebug;
  53.  
  54.  
  55.  
  56.         /** Called when the activity is first created. */
  57.  
  58.     @Override
  59.  
  60.     public void onCreate(Bundle icicle) {
  61.  
  62.         super.onCreate(icicle);
  63.  
  64.        
  65.  
  66.         // prepare the Layout
  67.  
  68.         // two Buttons
  69.  
  70.         // Debug-TextView Below
  71.  
  72.        
  73.  
  74.         LinearLayout linLayoutMain = new LinearLayout(this);
  75.  
  76.         linLayoutMain.setOrientation(LinearLayout.VERTICAL);
  77.  
  78.        
  79.  
  80.         LinearLayout linLayoutButtons = new LinearLayout(this);
  81.  
  82.         linLayoutButtons.setOrientation(LinearLayout.HORIZONTAL);
  83.  
  84.        
  85.  
  86.         // buttons
  87.  
  88.         MyCustomButton btn1 = new MyCustomButton(this, "btn1");
  89.  
  90.         MyCustomButton btn2 = new MyCustomButton(this, "btn2");
  91.  
  92.        
  93.  
  94.         // a TextView for debugging output
  95.  
  96.         mDebug = new TextView(this);
  97.  
  98.        
  99.  
  100.         // add button to the layout
  101.  
  102.         linLayoutButtons.addView(btn1,
  103.  
  104.                         new LinearLayout.LayoutParams(100, 100));
  105.  
  106.         linLayoutButtons.addView(btn2,
  107.  
  108.                         new LinearLayout.LayoutParams(100, 100));
  109.  
  110.        
  111.  
  112.         // add buttons layout and Text view to the Main Layout
  113.  
  114.         linLayoutMain.addView(linLayoutButtons,
  115.  
  116.                         new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
  117.  
  118.                                         LayoutParams.WRAP_CONTENT));
  119.  
  120.         linLayoutMain.addView(mDebug,
  121.  
  122.                         new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
  123.  
  124.                                         LayoutParams.WRAP_CONTENT));
  125.  
  126.        
  127.  
  128.         setContentView(linLayoutMain);
  129.  
  130.     }
  131.  
  132.    
  133.  
  134.    
  135.  
  136.     // Custom Button Class must extends Button,
  137.  
  138.     // because drawableStateChanged() is needed
  139.  
  140.     public class MyCustomButton extends Button {
  141.  
  142.  
  143.  
  144.         static final int StateDefault = 0;
  145.  
  146.         static final int StateFocused = 1;
  147.  
  148.         static final int StatePressed = 2;
  149.  
  150.        
  151.  
  152.  
  153.  
  154.         private int mState = StateDefault;
  155.  
  156.                 private Bitmap mBitmapDefault;
  157.  
  158.                 private Bitmap mBitmapFocused;
  159.  
  160.                 private Bitmap mBitmapPressed;
  161.  
  162.                 private String mCaption;
  163.  
  164.  
  165.  
  166.                 public MyCustomButton(Context context, String caption) {
  167.  
  168.                 super(context);
  169.  
  170.                 mCaption = caption;
  171.  
  172.                
  173.  
  174.                 setClickable(true);
  175.  
  176.                 // black Background on the View
  177.  
  178.                 setBackgroundColor(0xff000000);
  179.  
  180.                
  181.  
  182.                 // create for each State a Bitmap
  183.  
  184.                 // white Image
  185.  
  186.                 mBitmapDefault = Bitmap.createBitmap(100, 100, true);
  187.  
  188.                 // Blue Image
  189.  
  190.                 mBitmapFocused = Bitmap.createBitmap(100, 100, true);
  191.  
  192.                 // Green Image
  193.  
  194.                 mBitmapPressed = Bitmap.createBitmap(100, 100, true);
  195.  
  196.                
  197.  
  198.                 // create the Canvas
  199.  
  200.                 Canvas canvas = new Canvas();
  201.  
  202.                
  203.  
  204.                 // define on witch Bitmap should the Canvas draw
  205.  
  206.                 // default Bitmap
  207.  
  208.                 canvas.setDevice(mBitmapDefault);
  209.  
  210.                
  211.  
  212.                 // create the Drawing Tool (Brush)
  213.  
  214.                 Paint paint = new Paint();
  215.  
  216.                 paint.setAntiAlias(true);  // for a nicer paint
  217.  
  218.                
  219.  
  220.                 // draw a rectangle with rounded edges
  221.  
  222.                 // white Line
  223.  
  224.                 paint.setColor(0xffffffff);
  225.  
  226.                 // 3px line width
  227.  
  228.                 paint.setStrokeWidth(3);
  229.  
  230.                 // just the line, not filled
  231.  
  232.                 paint.setStyle(Style.STROKE);
  233.  
  234.                
  235.  
  236.                 // create the Path
  237.  
  238.                 Path path = new Path();
  239.  
  240.                 // rectangle with 10 px Radius
  241.  
  242.                 path.addRoundRect(new RectF(10, 10, 90, 90),
  243.  
  244.                                 10, 10, Direction.CCW);
  245.  
  246.                
  247.  
  248.                 // draw path on Canvas with the defined "brush"
  249.  
  250.                 canvas.drawPath(path, paint);
  251.  
  252.                
  253.  
  254.                 // prepare the "brush" for the Text
  255.  
  256.                 Paint paintText = new Paint();
  257.  
  258.                 paintText.setAntiAlias(true);
  259.  
  260.                 paintText.setTextSize(20);
  261.  
  262.                 paintText.setColor(0xffffffff);  // white
  263.  
  264.                
  265.  
  266.                 // draw Text
  267.  
  268.                 canvas.drawText(caption, 30, 55, paintText);
  269.  
  270.  
  271.  
  272.                 // do some more drawing stuff here...
  273.  
  274.  
  275.  
  276.                
  277.  
  278.                 // for the Pressed Image
  279.  
  280.                 canvas.setDevice(mBitmapPressed);
  281.  
  282.                
  283.  
  284.                 // Greed Color
  285.  
  286.                 paint.setColor(0xff00ff00);
  287.  
  288.                 paintText.setColor(0xff00ff00);  // white Line
  289.  
  290.                 canvas.drawPath(path, paint);
  291.  
  292.                 canvas.drawText(caption, 30, 55, paintText);
  293.  
  294.  
  295.  
  296.                 // do some more drawing stuff here...
  297.  
  298.                
  299.  
  300.                 // for the Pressed Image
  301.  
  302.                 canvas.setDevice(mBitmapFocused);
  303.  
  304.                
  305.  
  306.                 // Blue Color
  307.  
  308.                 paint.setColor(0xff0000ff);
  309.  
  310.                 paintText.setColor(0xff0000ff);  // white Line
  311.  
  312.                 canvas.drawPath(path, paint);
  313.  
  314.                 canvas.drawText(caption, 30, 55, paintText);
  315.  
  316.  
  317.  
  318.                 // do some more drawing stuff here...
  319.  
  320.  
  321.  
  322.                
  323.  
  324.                 // define OnClickListener for the Button
  325.  
  326.                 setOnClickListener(onClickListener);
  327.  
  328.                
  329.  
  330.         }
  331.  
  332.  
  333.  
  334.                 @Override
  335.  
  336.                 protected void onDraw(Canvas canvas) {
  337.  
  338.                         switch (mState) {
  339.  
  340.                         case StateDefault:
  341.  
  342.                                 canvas.drawBitmap(mBitmapDefault, 0, 0, null);
  343.  
  344.                                 mDebug.append(mCaption + ":default\n");
  345.  
  346.                                 break;
  347.  
  348.                         case StateFocused:
  349.  
  350.                                 canvas.drawBitmap(mBitmapFocused, 0, 0, null);
  351.  
  352.                                 mDebug.append(mCaption + ":focused\n");
  353.  
  354.                                 break;
  355.  
  356.                         case StatePressed:
  357.  
  358.                                 canvas.drawBitmap(mBitmapPressed, 0, 0, null);
  359.  
  360.                                 mDebug.append(mCaption + ":pressed\n");
  361.  
  362.                                 break;
  363.  
  364.                         }
  365.  
  366.                 }
  367.  
  368.                
  369.  
  370.                 @Override
  371.  
  372.                 protected void drawableStateChanged() {
  373.  
  374.                         if (isPressed()) {
  375.  
  376.                                 mState = StatePressed;
  377.  
  378.                         } else if (hasFocus()) {
  379.  
  380.                                 mState = StateFocused;
  381.  
  382.                         } else {
  383.  
  384.                                 mState = StateDefault;
  385.  
  386.                         }
  387.  
  388.                         // force the redraw of the Image
  389.  
  390.                         // onDraw will be called!
  391.  
  392.                         invalidate();
  393.  
  394.                 }
  395.  
  396.                
  397.  
  398.                 private OnClickListener onClickListener =
  399.  
  400.                         new OnClickListener() {
  401.  
  402.                         @Override
  403.  
  404.                         public void onClick(View arg0) {
  405.  
  406.                                 mDebug.append(mCaption + ":click\n");
  407.  
  408.                         }
  409.  
  410.                 };
  411.  
  412.     }
  413.  
  414. }
  415.  
  416.  
  417.  
  418.  
Parsed in 0.055 seconds, using GeSHi 1.0.8.4
User avatar
mauri
Junior Developer
Junior Developer
 
Posts: 13
Joined: Tue Dec 04, 2007 7:14 pm

Top

Postby bluefloyd8 » Fri Feb 15, 2008 9:56 pm

Maybe post a screen shot of what you are doing so we can all see!
User avatar
bluefloyd8
Experienced Developer
Experienced Developer
 
Posts: 70
Joined: Tue Jan 22, 2008 3:57 am
Location: Indiana, USA

Postby sm12 » Sun Nov 16, 2008 1:10 am

Ok here what Ive changed to be able to run the code on SDK 1.0:
I changed "true" parameter to "Config.RGB_565". I have no idea what it means, but I was able to run it. Other default enums of config also work (ARGB_4444, ARGB_8888). Can anyone explain what is it?

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. // create for each State a Bitmap
  2.           // white Image
  3.           mBitmapDefault = Bitmap.createBitmap(100, 100, Config.RGB_565);
  4.           // Blue Image
  5.           mBitmapFocused = Bitmap.createBitmap(100, 100, Config.RGB_565);
  6.           // Green Image
  7.           mBitmapPressed = Bitmap.createBitmap(100, 100, Config.RGB_565);
  8.  
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


also, instead canvas.setDevice(...) I put - canvas.setBitmap(...) - since setDevice was removed. I guess setBitmap has the exact same aim.

Output:
Attached file is a screenshot of output. When button is pressed white line turns to green, when focused (with navigation buttons) lines are blue.

Good tutorial, thanks!

BTW: What does "Config" and its value mean?

and is there a more compact way to do this?
Attachments
Picture 3.png
when focused
Picture 3.png (18.6 KiB) Viewed 8661 times
Picture 1.png
Output screenshot
Picture 1.png (16.76 KiB) Viewed 8661 times
sm12
Freshman
Freshman
 
Posts: 7
Joined: Thu Nov 13, 2008 4:36 am

Postby dkkundudolan » Wed Nov 19, 2008 12:15 pm

Hi mauri,

Very Good Tutorial. But one thing i want to know that, when i click on the btn1 or btn2, color is chaging. But i want to keep the changed color . means, when i click the white color btn1 , color turns to green. but if i leave pressing , color is going out. I want the green color will be there upto the next click.
So please, can anyone tell me how to do that? :(

Thanks a lot.....
dkkundudolan
Experienced Developer
Experienced Developer
 
Posts: 83
Joined: Mon Mar 03, 2008 12:50 pm

Postby Niketa » Wed Dec 03, 2008 12:44 pm

Hi,
I have tried this tutorial and its successfully run.
but when i tried to set Padding then its not working. i mean its no effect of Padding its only display which is by
default.

So if any solution is there then please tell me.

Thanks.
Niketa
Developer
Developer
 
Posts: 36
Joined: Wed Sep 17, 2008 12:37 pm

Top

Return to Advanced Tutorials

Who is online

Users browsing this forum: No registered users and 3 guests