Creating Custom Views - The ToggleButton

Basic Tutorials concerning: GUI, Views, Activites, XML, Layouts, Intents, ...

Creating Custom Views - The ToggleButton

Postby plusminus » Tue Dec 18, 2007 12:33 am

[align=center]This Tutorial is based on the code from benderamp posted here on anddev.
Creating Custom Views - The ToggleButton[/align]

What you will learn: You will learn how to create your own custom View, a ToggleButton. Also how to use custom Views in XML and JavaCode.

:?: Problems/Questions: Write it right below...

Difficulty: 1.5 of 5 :)

What it will look like:
[align=center] Unpressed State ..... and .... Pressed State
Image Image[/align]

Description:
0.) The easiest way to create an customized View is to extend an existing View. In this Tutorial, we will create a Toggle Button, which extends the ordinary Button provided by the SDK.

Create a class called ToggleButton.java:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public class ToggleButton extends Button {
Parsed in 0.032 seconds, using GeSHi 1.0.8.4

1.) As we want to have a ToggleButton we need to save if the Button is toggled or not.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         // ===========================================================
  2.  
  3.         // Fields
  4.  
  5.         // ===========================================================
  6.  
  7.  
  8.  
  9.         protected boolean isChecked = false;
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


2.) To use our View in Code we need a Constructor that passes the Context the ToggleButton was created in to the superclass which will handle everything that is to be done.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         // ===========================================================
  2.  
  3.         // Constructors
  4.  
  5.         // ===========================================================
  6.  
  7.         public ToggleButton(Context context) {
  8.  
  9.                 super(context);
  10.  
  11.         }
Parsed in 0.035 seconds, using GeSHi 1.0.8.4

3.) To make this View usable in XML-Layouts (this is called "inflate" or "inflating" we need another Constructor that passes the attributes like:
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1.           android:layout_width="fill_parent"
  2.  
  3.           android:layout_height="wrap_content"
  4.  
  5.           android:text="Toggle ME ..."
Parsed in 0.000 seconds, using GeSHi 1.0.8.4

to the superclass which will construct (inflate) the View using the parameters specified in xml. This is the constructor that will manage what I wrote:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.     public ToggleButton(Context context, AttributeSet attrs, Map params)
  2.  
  3.     {
  4.  
  5.         super(context, attrs, params);
  6.  
  7.     }
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


4.) We create a Getter-Method so one can check whether this ToggleButton is toggled or not:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         // ===========================================================
  2.  
  3.         // Getter & Setter
  4.  
  5.         // ===========================================================
  6.  
  7.         public boolean isChecked() {
  8.  
  9.                 return this.isChecked;
  10.  
  11.         }
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


5.) On every click to the ToggleBotton we want to toggle is state from 'toggled <--> untoggled':
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         // ===========================================================
  2.  
  3.         // Methods
  4.  
  5.         // ===========================================================
  6.  
  7.  
  8.  
  9.         @Override
  10.  
  11.         public boolean performClick() {
  12.  
  13.                 this.isChecked = !this.isChecked;
  14.  
  15.                 return super.performClick();
  16.  
  17.         }
Parsed in 0.036 seconds, using GeSHi 1.0.8.4

6.) The very last thing of this class is a bit more complicated.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         /** Return an array of resource IDs of
  2.  
  3.          * the Drawable states representing the
  4.  
  5.          * current state of the view. */
  6.  
  7.         @Override
  8.  
  9.         public int[] createDrawableState() {
  10.  
  11.                 int[] states;
  12.  
  13.                 if (this.isChecked()) {
  14.  
  15.                         // Checked
  16.  
  17.                         states = Button.PRESSED_STATE_SET;
  18.  
  19.                 } else {
  20.  
  21.                         // Unchecked
  22.  
  23.                         if (super.hasFocus()) {
  24.  
  25.                                 /* Unchecked && Focus
  26.  
  27.                                  * System highlights the Button */
  28.  
  29.                                 states = super.createDrawableState();
  30.  
  31.                         } else {
  32.  
  33.                                 // Unchecked && noFocus
  34.  
  35.                                 states = Button.LAST_STATE_SET;
  36.  
  37.                         }
  38.  
  39.                 }
  40.  
  41.                 return states;
  42.  
  43.         }
  44.  
  45. }
Parsed in 0.038 seconds, using GeSHi 1.0.8.4


7.) This is the way to use your Custom View in XML-Layouts. Instead of writing "<EditText ... />" you write the full package-path of the View plus its Class-Name. Of course you can use all Attributes that the superclass is capable of handling :!:
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <org.anddev.android.customviews.ToggleButton
  2.  
  3.          android:layout_width="fill_parent"
  4.  
  5.          android:layout_height="wrap_content"
  6.  
  7.          android:text="Toggle ME ..."/>
Parsed in 0.001 seconds, using GeSHi 1.0.8.4


8.) Now give it a try. SetUp a primitive Activity like this:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package org.anddev.android.customviews;
  2.  
  3.  
  4.  
  5. import android.app.Activity;
  6.  
  7. import android.os.Bundle;
  8.  
  9.  
  10.  
  11. public class CustomViews extends Activity {
  12.  
  13.     /** Called when the activity is first created. */
  14.  
  15.     @Override
  16.  
  17.     public void onCreate(Bundle icicle) {
  18.  
  19.         super.onCreate(icicle);
  20.  
  21.         setContentView(R.layout.main);
  22.  
  23.     }
  24.  
  25. }
Parsed in 0.037 seconds, using GeSHi 1.0.8.4


And set the following as main.xml:
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4.  
  5.    android:orientation="vertical"
  6.  
  7.    android:layout_width="fill_parent"
  8.  
  9.    android:layout_height="fill_parent"
  10.  
  11.    >
  12.  
  13. <TextView  
  14.  
  15.    android:layout_width="fill_parent"
  16.  
  17.    android:layout_height="wrap_content"
  18.  
  19.    android:text="Hello World, CustomViews"
  20.  
  21.    />
  22.  
  23. <org.anddev.android.customviews.ToggleButton
  24.  
  25.          android:layout_width="fill_parent"
  26.  
  27.          android:layout_height="wrap_content"
  28.  
  29.          android:text="Toggle ME ..."/>
  30.  
  31. </LinearLayout>
Parsed in 0.003 seconds, using GeSHi 1.0.8.4


[align=center]:) You will see the same as in the picture at the very top of this Tutorial :)[/align]

The Full Source:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package org.anddev.android.customviews;
  2.  
  3.  
  4.  
  5. import java.util.Map;
  6.  
  7.  
  8.  
  9. import android.content.Context;
  10.  
  11. import android.util.AttributeSet;
  12.  
  13. import android.widget.Button;
  14.  
  15.  
  16.  
  17. public class ToggleButton extends Button {
  18.  
  19.         // ===========================================================
  20.  
  21.         // Fields
  22.  
  23.         // ===========================================================
  24.  
  25.  
  26.  
  27.         protected boolean isChecked = false;
  28.  
  29.  
  30.  
  31.         // ===========================================================
  32.  
  33.         // Constructors
  34.  
  35.         // ===========================================================
  36.  
  37.         public ToggleButton(Context context) {
  38.  
  39.                 super(context);
  40.  
  41.         }
  42.  
  43.        
  44.  
  45.     public ToggleButton(Context context, AttributeSet attrs, Map params)
  46.  
  47.     {
  48.  
  49.         super(context, attrs, params);
  50.  
  51.     }
  52.  
  53.  
  54.  
  55.         // ===========================================================
  56.  
  57.         // Getter & Setter
  58.  
  59.         // ===========================================================
  60.  
  61.         public boolean isChecked() {
  62.  
  63.                 return this.isChecked;
  64.  
  65.         }
  66.  
  67.  
  68.  
  69.         // ===========================================================
  70.  
  71.         // Methods
  72.  
  73.         // ===========================================================
  74.  
  75.  
  76.  
  77.         @Override
  78.  
  79.         public boolean performClick() {
  80.  
  81.                 this.isChecked = !this.isChecked;
  82.  
  83.                 return super.performClick();
  84.  
  85.         }
  86.  
  87.  
  88.  
  89.         /** Return an array of resource IDs of
  90.  
  91.          * the Drawable states representing the
  92.  
  93.          * current state of the view. */
  94.  
  95.         @Override
  96.  
  97.         public int[] createDrawableState() {
  98.  
  99.                 int[] states;
  100.  
  101.                 if (this.isChecked()) {
  102.  
  103.                         // Checked
  104.  
  105.                         states = Button.PRESSED_STATE_SET;
  106.  
  107.                 } else {
  108.  
  109.                         // Unchecked
  110.  
  111.                         if (super.hasFocus()) {
  112.  
  113.                                 /* Unchecked && Focus
  114.  
  115.                                  * System highlights the Button */
  116.  
  117.                                 states = super.createDrawableState();
  118.  
  119.                         } else {
  120.  
  121.                                 // Unchecked && noFocus
  122.  
  123.                                 states = Button.LAST_STATE_SET;
  124.  
  125.                         }
  126.  
  127.                 }
  128.  
  129.                 return states;
  130.  
  131.         }
  132.  
  133. }
Parsed in 0.043 seconds, using GeSHi 1.0.8.4

[align=center]Thats it :)[/align]
Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Top

Postby benderamp » Fri Dec 21, 2007 7:40 am

Also a note in addition to the tutorial. Actually, android already has the class that represents toggle buttons - the CompoundButton - which already has the isCheched attribute, and also special listener class for its changes. So, it seems to be more natural to subclass from CompoundButton if one would like to implement the toggle button with custom drawing. But here is an unpleasant trap - if one would like to use standard graphics from usual Button to draw toggled/untoggled button states (like Button.LAST_STATE_SET etc) like in the tutorial, CompoundButton does not work here - if you try to change the base class in the tutorial from Button to CompoundButton, you will see that it is not drawn as on screenshots. I do not know the reason why it is so - probably Button's resource ids are not available in the CompoundButton, maybe CompoundButton overrides the onPaint() method on some unpleasant way, or maybe something else.
benderamp
Freshman
Freshman
 
Posts: 5
Joined: Sun Nov 25, 2007 5:19 am

Postby plusminus » Fri Dec 21, 2007 4:32 pm

Argh, why are they "hiding" components behind non-standard-names ^^

But one can still get the principles of creating custom views out of this tutorial ;)

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby daaain » Tue Mar 18, 2008 12:38 pm

hey,

i`m trying to get this work, but i get errors for createDrawableState() - it doesn`t exist anymore? i`ve tried onCreateDrawableState() and getDrawableState(), but i still couldn`t make it work, any ideas?


cheers,
dain
daaain
Once Poster
Once Poster
 
Posts: 1
Joined: Tue Mar 18, 2008 12:26 pm

createDrawableState() remove from m5

Postby KevGranD » Wed Apr 09, 2008 6:09 pm

Hi,

Sorry for my english, i'm french.

i've just read that createDrawableState() had been remove for Button, somebody can show how to replace this function?
ortherwise can somebody can explain me how to change button state by code?

Regards,
KevGranD
KevGranD
Once Poster
Once Poster
 
Posts: 1
Joined: Mon Mar 31, 2008 11:38 am
Location: France

Postby tim » Fri Aug 15, 2008 5:31 pm

the same problem here..
how to realise toggle butttons in m5 ???
User avatar
tim
Freshman
Freshman
 
Posts: 7
Joined: Thu Jul 03, 2008 3:05 pm

Top

Postby myhrvod » Sat Aug 16, 2008 4:09 pm

the same problem too.I find that this method be deleted in m5,see thisWeb Page Name
No best, Only better!
myhrvod
Freshman
Freshman
 
Posts: 7
Joined: Mon Aug 04, 2008 6:13 am

Postby JavaAndroid » Sun Oct 19, 2008 12:45 pm

Hi All,
its not working for me....i m getting error in this method


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public int[] createDrawableState() {
  2.  
  3.           int[] states;
  4.  
  5.           if (this.isChecked()) {
  6.  
  7.                // Checked
  8.  
  9.                states = Button.PRESSED_STATE_SET;
  10.  
  11.           } else {
  12.  
  13.                // Unchecked
  14.  
  15.                if (super.hasFocus()) {
  16.  
  17.                     /* Unchecked && Focus
  18.  
  19.                      * System highlights the Button */
  20.  
  21.                     states = super.createDrawableState();
  22.  
  23.                } else {
  24.  
  25.                     // Unchecked && noFocus
  26.  
  27.                     states = Button.LAST_STATE_SET;
  28.  
  29.                }
  30.  
  31.           }
  32.  
  33.           return states;
  34.  
  35.      }
  36.  
  37.  
Parsed in 0.038 seconds, using GeSHi 1.0.8.4


Also i m getting compile time error at this line
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. super(context, attrs,inflateParams);
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


in constructor of ToggleButton class...... Can anybody figure out this problem...How to make it work??

Thanks in Advance

Thanks
JavaAndroid
JavaAndroid
Freshman
Freshman
 
Posts: 7
Joined: Wed Oct 15, 2008 8:02 am

Postby goelsvaibhav » Mon Oct 20, 2008 8:00 am

Hi,

i am too getting the same errors..... :(

Thanks
Vaibhav
goelsvaibhav
Junior Developer
Junior Developer
 
Posts: 19
Joined: Fri Oct 17, 2008 7:07 am
Location: Gurgaon, India

custom view

Postby rahulp » Wed May 13, 2009 8:27 am

hi all...
is it possible to add custom components the way we add textview... and all.
i an using eclipse.. in the layout when i click add button i can get a list of widgets.. how can i add my custom view to it..
thanks in advance
rahul phadnis
rahulp
Developer
Developer
 
Posts: 30
Joined: Thu Feb 19, 2009 12:52 pm

About ToggleButton - how about iPhone-style ToggleButton?

Postby sunjavaduke » Sun May 31, 2009 10:26 am

Hi,

I think Android does not provide iPhone style toggle button?
Look at the picture below, when I just want to set ON|OFF for some settings, I think the iPhone style and Android style ToggleButton are both OK for me, but I have an application, I want to migrate it from iPhone SDK -> Android Platform?

Can someone give me a hint about how to do that?

P.S:
Because the iPhone style ToggleButton has a slider in it, so it supports drag&drop, Do I have to implement the TouchEvent listener?

Thanks.
Attachments
togglebutton.png
iPhone style toggle button.
togglebutton.png (3.06 KiB) Viewed 61903 times
The great thing in the world is not so much where we stand, as in what direction we are moving. - by Oliver Wendell Holmes
User avatar
sunjavaduke
Freshman
Freshman
 
Posts: 5
Joined: Tue Apr 21, 2009 11:09 am
Location: Shanghai, China

Toggle Image Button

Postby ioRek » Mon Jun 22, 2009 3:15 pm

hi, I need a ToggleButton which can have an Image.

Any idea on how can I make this happen ?
ioRek
Freshman
Freshman
 
Posts: 9
Joined: Mon Jun 22, 2009 3:10 pm

Postby ohyes » Fri Jul 10, 2009 3:12 am

JavaAndroid wrote:Hi All,
its not working for me...

Also i m getting compile time error at this line
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. super(context, attrs,inflateParams);
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


in constructor of ToggleButton class...... Can anybody figure out this problem...How to make it work??

Thanks in Advance

Thanks
JavaAndroid


Is there any-body could fix it :(
Please kindly help
Thank you,
-
ohyes
ohyes
Junior Developer
Junior Developer
 
Posts: 10
Joined: Fri Jul 10, 2009 2:51 am

Postby HBarker » Fri Dec 04, 2009 6:11 pm

JavaAndroid wrote:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public int[] createDrawableState() {
  2.           int[] states;
  3.           if (this.isChecked()) {
  4. ...
  5.      }
  6.  
Parsed in 0.037 seconds, using GeSHi 1.0.8.4



I believe this method was changed the following works Notice also the Button state enumerations changed as well.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         protected int[] onCreateDrawableState(int extraSpace) {
  2.         int[] states;
  3.         if (this.isChecked()) {
  4.              // Checked
  5.              states = Button.PRESSED_ENABLED_SELECTED_STATE_SET;
  6.         } else {
  7.              // Unchecked
  8.              if (super.hasFocus()) {
  9.                   /* Unchecked && Focus
  10.                    * System highlights the Button */
  11.                   states = super.onCreateDrawableState(extraSpace);
  12.              } else {
  13.                   // Unchecked && noFocus
  14.                   states = Button.EMPTY_STATE_SET;
  15.              }
  16.         }
  17.         return states;
  18.         }
  19.  
Parsed in 0.039 seconds, using GeSHi 1.0.8.4


I think its important for the people out there that are just learning to learn not just the answer but how to find the answer. Taking the information I knew from the original tutorial I went to the android Developer site and searched for this function createDrawableState. Notice that it shows up in Button and In view. This is because of Inheritance Button inherits from TextView and View. But when you pull up either of those links there isn't a createDrawableState hitting search in the browser (control f) found onCreateDrawableState. Now that I had a hunch that I had the right method in eclipse I right clicked > Source > Overide Implement Methods Scrolled through them until I found my function.

JavaAndroid wrote:Also i m getting compile time error at this line
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. super(context, attrs,inflateParams);
Parsed in 0.036 seconds, using GeSHi 1.0.8.4

in constructor of ToggleButton class...... Can anybody figure out this problem...How to make it work??


Again this is a similar issue as the first one the methods have changed a little bit its something you'll have to get used to dealing with and Solving. If you noticed in my explanation of the other problem if you right click > Source there is alot of short cut learning goodness here. You'll notice constructors as well give a try at generating the constructors. you'll Notice that the params is no longer a Map its an int. So you'll have to modify your code somewhat to meet that expectation.
HBarker
Junior Developer
Junior Developer
 
Posts: 11
Joined: Fri Dec 04, 2009 5:54 pm

Postby HBarker » Fri Dec 04, 2009 6:13 pm

To the Original Poster of this tutorial thanks a lot on posting this. It helped me tremendously and opened my eyes to how easy it is to create custom components.
HBarker
Junior Developer
Junior Developer
 
Posts: 11
Joined: Fri Dec 04, 2009 5:54 pm

Top
Next

Return to Novice Tutorials

Who is online

Users browsing this forum: No registered users and 3 guests