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.

Difficulty: 1.5 of 5

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


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:
Using java Syntax Highlighting
- public class ToggleButton extends Button {
Parsed in 0.010 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.
Using java Syntax Highlighting
- // ===========================================================
- // Fields
- // ===========================================================
- protected boolean isChecked = false;
Parsed in 0.010 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.
Using java Syntax Highlighting
- // ===========================================================
- // Constructors
- // ===========================================================
- public ToggleButton(Context context) {
- super(context);
- }
Parsed in 0.010 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:
Using xml Syntax Highlighting
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- 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:
Using java Syntax Highlighting
- public ToggleButton(Context context, AttributeSet attrs, Map params)
- {
- super(context, attrs, params);
- }
Parsed in 0.010 seconds, using GeSHi 1.0.8.4
4.) We create a Getter-Method so one can check whether this ToggleButton is toggled or not:
Using java Syntax Highlighting
- // ===========================================================
- // Getter & Setter
- // ===========================================================
- public boolean isChecked() {
- return this.isChecked;
- }
Parsed in 0.010 seconds, using GeSHi 1.0.8.4
5.) On every click to the ToggleBotton we want to toggle is state from 'toggled <--> untoggled':
Using java Syntax Highlighting
- // ===========================================================
- // Methods
- // ===========================================================
- @Override
- public boolean performClick() {
- this.isChecked = !this.isChecked;
- return super.performClick();
- }
Parsed in 0.010 seconds, using GeSHi 1.0.8.4
6.) The very last thing of this class is a bit more complicated.
Using java Syntax Highlighting
- /** Return an array of resource IDs of
- * the Drawable states representing the
- * current state of the view. */
- @Override
- public int[] createDrawableState() {
- int[] states;
- if (this.isChecked()) {
- // Checked
- states = Button.PRESSED_STATE_SET;
- } else {
- // Unchecked
- if (super.hasFocus()) {
- /* Unchecked && Focus
- * System highlights the Button */
- states = super.createDrawableState();
- } else {
- // Unchecked && noFocus
- states = Button.LAST_STATE_SET;
- }
- }
- return states;
- }
- }
Parsed in 0.011 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

Using xml Syntax Highlighting
- <org.anddev.android.customviews.ToggleButton
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Toggle ME ..."/>
Parsed in 0.000 seconds, using GeSHi 1.0.8.4
8.) Now give it a try. SetUp a primitive Activity like this:
Using java Syntax Highlighting
- package org.anddev.android.customviews;
- import android.app.Activity;
- import android.os.Bundle;
- public class CustomViews extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- setContentView(R.layout.main);
- }
- }
Parsed in 0.011 seconds, using GeSHi 1.0.8.4
And set the following as main.xml:
Using xml Syntax Highlighting
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Hello World, CustomViews"
- />
- <org.anddev.android.customviews.ToggleButton
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Toggle ME ..."/>
- </LinearLayout>
Parsed in 0.001 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

The Full Source:
Using java Syntax Highlighting
- package org.anddev.android.customviews;
- import java.util.Map;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.widget.Button;
- public class ToggleButton extends Button {
- // ===========================================================
- // Fields
- // ===========================================================
- protected boolean isChecked = false;
- // ===========================================================
- // Constructors
- // ===========================================================
- public ToggleButton(Context context) {
- super(context);
- }
- public ToggleButton(Context context, AttributeSet attrs, Map params)
- {
- super(context, attrs, params);
- }
- // ===========================================================
- // Getter & Setter
- // ===========================================================
- public boolean isChecked() {
- return this.isChecked;
- }
- // ===========================================================
- // Methods
- // ===========================================================
- @Override
- public boolean performClick() {
- this.isChecked = !this.isChecked;
- return super.performClick();
- }
- /** Return an array of resource IDs of
- * the Drawable states representing the
- * current state of the view. */
- @Override
- public int[] createDrawableState() {
- int[] states;
- if (this.isChecked()) {
- // Checked
- states = Button.PRESSED_STATE_SET;
- } else {
- // Unchecked
- if (super.hasFocus()) {
- /* Unchecked && Focus
- * System highlights the Button */
- states = super.createDrawableState();
- } else {
- // Unchecked && noFocus
- states = Button.LAST_STATE_SET;
- }
- }
- return states;
- }
- }
Parsed in 0.014 seconds, using GeSHi 1.0.8.4
[align=center]Thats it

Regards,
plusminus