Live character count for EditText
AndroidAndroid Problem Overview
I was wondering what the best way to do a live character count of an edit-text box is in Android. I was looking at http://developer.android.com/reference/android/view/KeyEvent.html">this</a> but I couldn't seem to make any sense of it.
To describe the problem, I have an EditText and I'm trying to limit the characters to 150. I can do this with an input filter, however I want to show right below the text box the number of characters a user has entered(Almost like stack overflow is doing right now).
If someone could write a small snippet of example code or point me in the right direction I'd appreciate it a lot.
Android Solutions
Solution 1 - Android
you can use a TextWatcher to see when the text has changed
private TextView mTextView;
private EditText mEditText;
private final TextWatcher mTextEditorWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
//This sets a textview to the current length
mTextView.setText(String.valueOf(s.length()));
}
public void afterTextChanged(Editable s) {
}
};
you set the TextWatcher for the edittext with
mEditText.addTextChangedListener(mTextEditorWatcher);
Solution 2 - Android
You can do character counting from xml itself using TextInputLayout wrapper for EditText introduced in SupportLibrary v23.1
Just wrap your EditText with a TextInputLayout and set CounterEnabled to true and Set a counterMaxLength.
<android.support.design.widget.TextInputLayout
android:id="@+id/textContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
app:counterMaxLength="20"
>
<EditText
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Text Hint"
/>
</android.support.design.widget.TextInputLayout>
You'll get a material effect like this
You may use counterOverflowTextAppearance , counterTextAppearance to style the counter.
EDIT
From Android documentation.
The TextInputEditText class is provided to be used as a child of this layout. Using TextInputEditText allows TextInputLayout greater control over the visual aspects of any text input. An example usage is as so:
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/form_username"/>
</android.support.design.widget.TextInputLayout>
Solution 3 - Android
You can do it with TextInputLayout
and compat libraries with:
app:counterEnabled="true"
app:counterMaxLength="420"
and complete:
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
app:counterMaxLength="420">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="420" />
</android.support.design.widget.TextInputLayout>
Solution 4 - Android
in xml add this attribute for editText
android:maxLength="80"
in java add this listener
ed_caption.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
tv_counter.setText(80 - s.toString().length() + "/80");
}
});
Solution 5 - Android
Its very Simple Follow the instructions below:
====Add them to your Imports===
import android.text.Editable;
import android.text.TextWatcher;
=====Define this=====
private TextView sms_count;
==========Inside On Create=====
sms_count = (TextView) findViewById(R.id.textView2);
final TextWatcher txwatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
sms_count.setText(String.valueOf(s.length()));
}
public void afterTextChanged(Editable s) {
}
};
sms_message.addTextChangedListener(txwatcher);
Solution 6 - Android
You can add a counter to your TextInputEditText being wrapped in a TextInputLayout. As you can see in the example, counterEnabled
enables this feature and counterMaxLengh
defines the number of characters for it.
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
app:counterMaxLength="50">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_title"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>
Solution 7 - Android
You can use TextWatcher class to see text has changed and how much number of character remains.Here i have set counter of 140 characters.
EditText typeMessageToPost;
TextView number_of_character;
public void onCreate(Bundle savedBundleInstance) {
super.onCreate(savedBundleInstance);
setContentView(R.layout.post_activity);
typeMessageToPost.addTextChangedListener(mTextEditorWatcher);
}
private final TextWatcher mTextEditorWatcher=new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
number_of_character.setText(String.valueOf(140-s.length()));
}
};
Solution 8 - Android
Just set these 2 lines in TextInputLayout
in your XML file:
app:counterEnabled="true"
app:counterMaxLength="200"
Solution 9 - Android
This solution uses Kotlin
and shows the number of characters left. Also, if the current number of characters surpasses the limit of 50, the text color will change to red.
Kotlin
private val mTitleTextWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if(YOUR_EDIT_TEXT_ID.text.toString().trim().length < 51){
YOUR_CHAR_LEFT_TEXTVIEW_ID.text = (50 - YOUR_EDIT_TEXT_ID.text.toString().trim().length).toString()
YOUR_CHAR_LEFT_TEXTVIEW_ID.setTextColor(Color.BLACK)
}
else{
YOUR_CHAR_LEFT_TEXTVIEW_ID.text = "0"
YOUR_CHAR_LEFT_TEXTVIEW_ID.setTextColor(Color.RED)
}
}
override fun afterTextChanged(s: Editable) {}
}
Also, don't forget to add the TextWatcher
to your EditText
YOUR_EDIT_TEXT_ID.addTextChangedListener(mTitleTextWatcher)
Solution 10 - Android
I met the same problem and I tried Cameron's method. It works but there is a minor bug: If the user use copy and paste then it fails to count the chars. So I suggest to do after the text changed, like below:
private final TextWatcher mTextEditorWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void afterTextChanged(Editable s) {
//This sets a textview to the current length
mTextView.setText(String.valueOf(s.length()));
}
};
Solution 11 - Android
Use android:maxLength="140"
That should work. :)
Hope that helps
Solution 12 - Android
edtmm.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int data = Integer.parseInt(String.valueOf(s.length()));
if (data == 2) {
edtdd.requestFocus();
} else {
edtmm.requestFocus();
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
Solution 13 - Android
Try doing something like this.
This solution may be more performant as opposed to getting CharSequence.length. Each time you tap on the soft keyboard the event fires; therefore, if you do a length it will count the CharSequence each time, which may slow if you start getting into large CharSequnces. The event listener on text change tacks the before and after count. This works well for increment and decrement values
@Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
int tick = start + after;
if(tick < mMessageMax) {
int remaining = mMessageMax - tick;
((TextView)findViewById(R.id.contact_us_chars)).setText(String.valueOf(remaining));
}
}
Solution 14 - Android
try this
private TextWatcher textWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
editText.post(new Runnable() {
@Override
public void run() {
if (length < 100) {
if (count > 0 && after <= 0)/*remove emoij*/ {
length--;
} else if (count > after)/*remove text*/ {
length--;
} else if (count == 0 && after > 1)/*emoij*/ {
++length;
} else if (count == 0 && after == 1)/*Text*/ {
++length;
} else if (count > 0 && after > 1) {
++length;
}
if (s.length() <= 0)
length = 0;
Log.w("MainActivity", " Length: " + length);
} else {
if (count > 0 && after <= 0)/*remove emoij*/ {
length--;
} else if (count > after)/*remove text*/ {
length--;
}
Log.w("MainActivity", " Length: " + length);
}
if (length == 100) {
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(s.length())});
} else {
editText.setFilters(new InputFilter[]{});
}
}
});
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
}
};
`
Solution 15 - Android
Clear way;
abstract class CharacterWatcher : TextWatcher {
override fun afterTextChanged(text: Editable?) {
afterCharacterChanged(text?.lastOrNull(), text?.length)
}
override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, before: Int) {}
override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) {}
abstract fun afterCharacterChanged(char: Char?, count: Int?)
}
editText.addTextChangedListener(new CharacterWatcher() {
@Override
public void afterCharacterChanged(@Nullable Character character, @Nullable Integer count) {
action()
}
});