| Author |
Message |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2102 Location: Germany
|
Posted: Tue Dec 18, 2007 12:33 am Post subject: Creating Custom Views - The ToggleButton |
|
|
This Tutorial is based on the code from benderamp posted here on anddev.
Creating Custom Views - The ToggleButton
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:
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:
| Java: | public class ToggleButton extends Button { |
1.) As we want to have a ToggleButton we need to save if the Button is toggled or not.
| Java: | // ===========================================================
// Fields
// ===========================================================
protected boolean isChecked = false; |
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.
| Java: | // ===========================================================
// Constructors
// ===========================================================
public ToggleButton(Context context) {
super(context);
} |
3.) To make this View usable in XML-Layouts (this is called "inflate" or "inflating" we need another Constructor that passes the attributes like:
| XML: | android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Toggle ME ..." |
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:
| Java: | public ToggleButton(Context context, AttributeSet attrs, Map params)
{
super(context, attrs, params);
} |
4.) We create a Getter-Method so one can check whether this ToggleButton is toggled or not:
| Java: | // ===========================================================
// Getter & Setter
// ===========================================================
public boolean isChecked() {
return this.isChecked;
} |
5.) On every click to the ToggleBotton we want to toggle is state from 'toggled <--> untoggled':
| Java: | // ===========================================================
// Methods
// ===========================================================
@Override
public boolean performClick() {
this.isChecked = !this.isChecked;
return super.performClick();
} |
6.) The very last thing of this class is a bit more complicated.
| Java: | /** 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;
}
} |
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
| XML: | <org.anddev.android.customviews.ToggleButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Toggle ME ..."/> |
8.) Now give it a try. SetUp a primitive Activity like this:
| Java: | 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);
}
} |
And set the following as main.xml:
| XML: | <?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> |
 You will see the same as in the picture at the very top of this Tutorial 
The Full Source:
| Java: | 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;
}
} |
Thats it 
Regards,
plusminus _________________
| Android Development Community / Tutorials |
|
| Back to top |
|
 |
benderamp Freshman
Joined: 25 Nov 2007 Posts: 5
|
Posted: Fri Dec 21, 2007 7:40 am Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2102 Location: Germany
|
Posted: Fri Dec 21, 2007 4:32 pm Post subject: |
|
|
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 _________________
| Android Development Community / Tutorials |
|
| Back to top |
|
 |
daaain Once Poster
Joined: 18 Mar 2008 Posts: 1
|
Posted: Tue Mar 18, 2008 12:38 pm Post subject: |
|
|
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 |
|
| Back to top |
|
 |
KevGranD Once Poster
Joined: 31 Mar 2008 Posts: 1 Location: France
|
Posted: Wed Apr 09, 2008 6:09 pm Post subject: createDrawableState() remove from m5 |
|
|
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 |
|
| Back to top |
|
 |
tim Freshman

Joined: 03 Jul 2008 Posts: 6
|
Posted: Fri Aug 15, 2008 5:31 pm Post subject: |
|
|
the same problem here..
how to realise toggle butttons in m5 ??? |
|
| Back to top |
|
 |
myhrvod Freshman
Joined: 04 Aug 2008 Posts: 6
|
Posted: Sat Aug 16, 2008 4:09 pm Post subject: |
|
|
the same problem too.I find that this method be deleted in m5,see thisWeb Page Name _________________ No best, Only better! |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
© 2007, Android Development Community
All rights reserved.
Powered by phpBB.
|