[Java for Android App Development] bassie1995:
Hello everyone,

As most of you probably have, I have been working on an app that lets users input text in an EditText. However, this app possibly gets a lot of input from the user, which can lead to multiple lines of text in either of two EditTexts!

Naturally, this can result in some real headaches: when you want to clear the EditText, you'll have to delete character after character from it.

So, I decided to go on a quest. Hunt down a solution that's fat, easy to implement and works nicely from the user's prespective. Of course, it'd be nice if it looks cool, too.

This is where I came across a blog post, after some browsing of StackOverflow, that detailed a nice and quick fix.

Today, I will be explaining to all of you how to implement this, and even add a couple of little extras.

Step 1: Creating the custom View's XML layout

The first thing you have to do, since this is a custom View, is create its XML layout. Luckily, this isn't too hard:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >

<EditText
android:id="@+id/clearable_edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingRight="35dip" />

<Button
android:id="@+id/clearable_button_clear"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dip"
android:background="@drawable/ic_clear" />

</RelativeLayout>

Some explanation: This is just a layout declaration. Later on, when making the ClearableEditText constructor, you'll have to call upon the elements in this layout.

Step 2: Making the class

To create an own new View, you have to extend from one of the standard View classes. Since you are including a Button and EditText in the one (creating a compound View), RelativeLayout is a good choice.

In the constructors of the class - which overrides the stock EditText constructors - is where you inflate the layout, which has been done by adding a method initViews().

The method to pay attention to here is showHideClearButton. An addTextChangedListener call is made, which conveniently takes a TextWatcher as its parameter. That means we can easily see when something about the input changes, and act upon it.

Some methods have to be implemented, but onTextChanged is the only one we'll really need. Here, we can check the length of the String that's been entered, and see whether to hide or show to cross Button for clearing the EditText.

The code speaks for itself from here on out:

import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;

public class ClearableEditText extends RelativeLayout {
LayoutInflater inflater = null;
EditText edit_text;
Button btn_clear;

public ClearableEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initViews();
}

public ClearableEditText(Context context, AttributeSet attrs) {
super(context, attrs);
initViews();

}

public ClearableEditText(Context context) {
super(context);
initViews();
}

void initViews() {
inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.clearable_edit_text, this, true);
edit_text = (EditText) findViewById(R.id.clearable_edit);
btn_clear = (Button) findViewById(R.id.clearable_button_clear);
btn_clear.setVisibility(RelativeLayout.INVISIBLE);
clearText();
showHideClearButton();
}

void clearText() {
btn_clear.setOnClickListener(new OnClickListener() {
[MENTION=439709]override[/MENTION]
public void onClick(View v) {
edit_text.setText("");
}
});
}

void showHideClearButton() {
edit_text.addTextChangedListener(new TextWatcher() {

[MENTION=439709]override[/MENTION]
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (s.length() > 0)
btn_clear.setVisibility(RelativeLayout.VISIBLE);
else
btn_clear.setVisibility(RelativeLayout.INVISIBLE);
}

[MENTION=439709]override[/MENTION]
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {

}

[MENTION=439709]override[/MENTION]
public void afterTextChanged(Editable s) {

}
});
}

public Editable getText() {
Editable text = edit_text.getText();
return text;
}
}

Step 3: Using the ClearableEditText

So now, we have a (hopefully) fully functional implementation. We are still missing something, though! Of course, we haven't implemented our own solution into the code yet.

Luckily, this is very easy and takes mere seconds.

To use your ClearableEditText in a layout, simply add its full path to one of the elements, like so:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<[packagename].ClearableEditText
android:id=”@+id/edit_text_clearable”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content” />

</LinearLayout>

See? Very easy. There is still one minor issue, though...

Step 4: Finishing touches - setting attributes

As you have probably eagerly tried, the above code should completely work and give you a working clearable EditText.

Of course, since there's no free lunch in computer science, there's a catch: no attributes can be set from your layout's XML file (the number of lines, text size, etc.).

So, I thought up a very simple way of doing this programatically, from your Java code. These supplements does take extra lines in your class' code, but will do exactly the same as their XML counterparts.

In your ClearableEditText class, to set the input type, hint and maximum number of lines, add:

public void setHint(int encode) {
edit_text.setHint(encode);
}

public void setMaxLines(int lines) {
edit_text.setMaxLines(lines);
}

public void setType(int type) {
edit_text.setInputType(type);
}

Then, in your main class, where you're calling those methods:

<editTextName>.setHint("Hello world!");
<editTextName>.setMaxLines(5);
<editTextName>.setType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);

Keep in mind these are examples. The setType call will set the ClearableEditText to only receive numbers, which can be positive and negative (signed, after the sign bit in bit notation). I recommend you look up the API entry for it, or Google for it.

This can be done for - seemingly, mind - any type of attribute. I've used this for text size, number of lines, to get the text, and the above examples.

Should you have anymore questions or things to say about this, please do so!

Have fun,

bassie1995

P.S.: Big thanks to the creator of the original blog post. Thanks ab1209!