I have a requirement that Edittext should have all words start with Capital letter. If the user writes it in a smaller case(first letter of the word), then also it should be converted it into Uppercase.
I have done it in layout as below so far :
<EditText
android:id="#+id/edGymName"
style="#style/LoginRegisterEditText"
android:layout_marginTop="#dimen/size_10"
android:layout_toLeftOf="#+id/txtStatusGymStatus"
android:hint="#string/gym_tag"
android:inputType="textPersonName|textCapWords|textNoSuggestions"
android:maxLength="30" />
But, I don't want to allow the user to write the first letter of the word in the small letter. This is working but the user is able to write the first letter of the word in the small case. What if we forcefully do not allow it.
Set the input type to TYPE_CLASS_TEXT| TYPE_TEXT_FLAG_CAP_CHARACTERS.
android:inputType="textCapCharacters" for every character
android:inputType="textCapSentences" for senteces
android:inputType="textCapWords" for every words
Use this it will work.
android:inputType="textCapSentences"
In your case
<EditText
android:id="#+id/edGymName"
style="#style/LoginRegisterEditText"
android:layout_marginTop="#dimen/size_10"
android:layout_toLeftOf="#+id/txtStatusGymStatus"
android:hint="#string/gym_tag"
android:inputType="textCapSentences"
android:maxLength="30" />
Change input type to input type to TYPE_CLASS_TEXT| TYPE_TEXT_FLAG_CAP_CHARACTERS.
android:inputType="text|textCapCharacters"
or from java code
editText.setInputType(InputType.TYPE_CLASS_TEXT |InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
Statically (i.e. in your layout XML file): set
android:inputType="textCapSentences" on your EditText.
Programmatically: you have to include InputType.TYPE_CLASS_TEXT in the InputType of the EditText, e.g.
EditText editor = new EditText(this);
editor.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
User can manually change the text caps from Soft keyBoard to manage this case you can set a input filter. Android provide a AllCap filter for this.
edittext.setFilters(new InputFilter[] {new InputFilter.AllCaps()});
Setting filter will reset some other attribute which you set in manifest. So beware of it . Like if you have set maxlenth attribute set in xml then after setting filter you need to reset it at runtime otherwise it won't work . Below is and example.
editText.setFilters(new InputFilter[] {new InputFilter.AllCaps(),new InputFilter.LengthFilter(40)});
So the best way to do it Prevent all previous filter and just add a new one.
InputFilter[] oldFilters = editText.getFilters();
InputFilter[] newFilters = new InputFilter[oldFilters.length + 1];
System.arraycopy(oldFilters, 0, newFilters, 0, oldFilters.length);
newFilters[oldFilters.length] = new InputFilter.AllCaps();
editText.setFilters(newFilters);
This will forcefully retype your whole text/sentence from your editText and make every first letter of the word capital:
String oldText = ""; //this must be outside the method where the addTextChangedListener on the editText is set. (Preferrably outside the onCreate())
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
if (editable.toString().length() > 0 &&
!editable.toString().equals(oldText)) {
oldText = editable.toString(); //prevent infinite loop
editText.setText(capitalizeFirstLetterWord(editable.toString()));
editText.setSelection(editText.getText().length()); //set the cursor to the end of the editText
}
}
});
method called: (I've modified it a little bit, refer to the link)
/**
* reference: http://www.penguincoders.net/2015/06/program-to-capitalize-first-letter-of-each-word-in-java.html
*
* #param s sentence to be capitalize each first letter of each word
* #return capitalized sentence
*/
public static String capitalizeFirstLetterWord(String s) {
StringBuilder cap = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
try {
char x = s.charAt(i);
if (x == ' ') {
cap.append(" ");
char y = s.charAt(i + 1);
cap.append(Character.toUpperCase(y));
i++;
} else {
cap.append(x);
}
} catch (IndexOutOfBoundsException ignored) {
}
}
//finally, capitalize the first letter of the sentence
String sentence = cap.toString();
if (sentence.length() > 0) {
sentence = String.valueOf(sentence.charAt(0)).toUpperCase(); //capitalize first letter
if (cap.toString().length() > 1) { //check if there's succeeding letters
sentence += cap.toString().substring(1); //append it also
}
}
return sentence;
}
I am working on app where i use Urdu Custom Keyboard its work fine but the problem is that when i type any-word e.g. (سلام), cursor become not works at mid character for example cut/copy/paste or deleting (ا) character from the mid from word are not work.
i uses rough technique just appending characters but is also work fine.
For taping any alphabetic
private void addText(View v) {
// String b = "";
// b = (String) v.getTag();
// urdu_word.setText(b);
if (isEdit == true) {
String b = "";
b = (String) v.getTag();
if (b != null) {
Log.i("buttonsOnclick", b);
// adding text in Edittext
mEt.append(b);
}
}
}
For back button tapping
private void isBack(View v) {
if (isEdit == true) {
CharSequence cc = mEt.getText();
if (cc != null && cc.length() > 0) {
{
mEt.setText("");
mEt.append(cc.subSequence(0, cc.length() - 1));
}
}
}
}
Here the screenshot clear my problem to you people
I used a lot of library and code from github but don't catch good idea
1) Keyboard-1
2) Keyboard-2
3) Keyboard-3
4) Keyboard-4
i checked all these keyboard and more from libs, have same cursor issue, how to manage fully my custom keyboard by deleting character from mid and copy my written text copy paste like normal keyboard with EditText, thanks in advance all of you :)
Thanks God i solved my issue using simple logic.
For back button
private void isBack(View v) {
// char[] tempChar = null;
if ((mEt.getText().toString().length() > 0)) {
int temp = mEt.getSelectionEnd() - 1;
if (temp >= 0) {
mEt.setText((mEt.getText().toString()
.substring(0, mEt.getSelectionEnd() - 1).concat(mEt
.getText()
.toString()
.substring(mEt.getSelectionEnd(),
mEt.getText().length()))));
mEt.setSelection(temp);
}
}
}
For adding any character
private void addText(View v) {
int temp = mEt.getSelectionEnd();
if (temp >= 0) {
String b = "";
b = (String) v.getTag();
mEt.setText((mEt.getText().toString()
.substring(0, mEt.getSelectionEnd()) + b.concat(mEt
.getText().toString()
.substring(mEt.getSelectionEnd(), mEt.getText().length()))));
mEt.setSelection(temp + 1);
}
}
for copy paste i added few lines code to EditText
<EditText
android:id="#+id/xEt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#drawable/edittextshape"
android:ems="10"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="top"
android:imeOptions="actionDone"
android:padding="15dp"
android:singleLine="false"
android:visibility="visible" />
Suppose when a field is loaded, its empty. When the user types 1, it says 0.01, then he types another 0 after the 1 (10) it becomes 0.10. When he types another 1, it becomes 1.10.
Just like entering the price of a product. How do I do that on Android? I'm quite stumped to be honest since I've never tried something like this. Is there some special input method for this?
Here's the code I wrote for myself:
private String addCurrencySign(String digits) {
String string = "£";
// Amount length greater than 2 means we need to add a decimal point
if (digits.length() > 2) {
String pound = digits.substring(0, digits.length() - 2); // Pound part
String pence = digits.substring(digits.length() - 2); // Pence part
string += pound + "." + pence;
} else if (digits.length() == 1) {
string += "0.0" + digits;
Log.d(TAG, "length 1 " + string);
} else if (digits.length() == 2) {
string += "0." + digits;
Log.d(TAG, "length 2 " + string);
}
return string;
}
This addCurrencySign method is triggered each time when user trying to type on the number pad. The number pad is consist of several digit buttons (just like POS handheld or calculator).
Since you don't need to build a keypad with buttons, could you try intercept the keyboard events, which is described in Handling Keyboard Actions and maybe write something like this:
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_0:
return true;
case KeyEvent.KEYCODE_1:
return true;
case KeyEvent.KEYCODE_2:
return true;
case KeyEvent.KEYCODE_3:
return true;
......
default:
return super.onKeyUp(keyCode, event);
}
}
Maybe you don't have to use switch clause, my idea is to intercept the key entering 0~9 digits and for each 0~9, call addCurrencySign method.
Use:
TextWatcher watcher = new TextWatcher(){
afterTextChanged(Editable s){}
beforeTextChanged(CharSequence s, int start, int count, int after){}
onTextChanged(CharSequence s, int start, int before, int count){}
}
yourEditText.addTextChangedListener(watcher);
Here you will find more info about TextWatcher http://developer.android.com/reference/android/text/TextWatcher.html
OK guys.. I have a temporary workaround. This can't be termed as the perfect solution but its a workaround that works well in my case.
I couldn't figure out a way to stop the stackoverflow error. My workaround? Make the EditText field take input, but display the currency output onto a TextView, and make the EditText disappear from the UI so the user can't see that he is typing just 1234 instead of 12.34.
Here is the code. The addCurrencySign function comes from #ss1271.
amountpaid.addTextChangedListener(new TextWatcher()
{
#Override public void onTextChanged(CharSequence s, int start, int before, int count)
{
amount.setText(addCurrencySign(s.toString()));
}
#Override public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
#Override public void afterTextChanged(Editable s)
{
}
});
Here's the function that the user posted. It works very well.
private String addCurrencySign(String digits)
{
String string = "&"; // Your currency
// Amount length greater than 2 means we need to add a decimal point
if (digits.length() > 2)
{
String pound = digits.substring(0, digits.length() - 2); // Pound
// part
String pence = digits.substring(digits.length() - 2); // Pence part
string += pound + "." + pence;
}
else if (digits.length() == 1)
{
string += "0.0" + digits;
Log.d("TextWatcher", "length 1 " + string);
}
else if (digits.length() == 2)
{
string += "0." + digits;
Log.d("TextWatcher", "length 2 " + string);
}
return string;
}
Here's the 'invisible' edittext:
<EditText
android:id="#+id/amoundpaid"
android:layout_width="1dp"
android:layout_height="1dp"
android:background="#00000000"
android:ems="10"
android:inputType="number"
android:textColor="#00ffffff" >
<requestFocus />
Here's the field that will show the output text (with currency sign and proper decimal point value):
<TextView
android:id="#+id/amount"
android:layout_width="210dp"
android:layout_height="50dp"
android:background="#80000000"
android:gravity="center|center_vertical"
android:textColor="#ffffff"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium" />
I know this is not a optimum solution, but it works. I needed the functionality and this is what I had to do to get it. If someone can fix the stackoverflow error, please post and mods will change the answer to that one (once its verified).
is there a way to set a custom space (in pixels) between letters to an editText? I found only how to set spaces between the lines, but bot between letters on the same row
Using android:letterSpacing i was able to add spacing between characters in a textview
<android.support.v7.widget.AppCompatTextView
android:id="#+id/textViewValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:letterSpacing="0.35"
android:maxLines="1" />
Related methods:
setLetterSpacing(float)
I had to do this myself today so here are some updates about this problem :
From API 21 you can use XML attribute android:letterSpacing="2" or from code myEditText.setLetterSpacing(2);
Before API 21, use a TextWatcher with the following code
private static final String LETTER_SPACING = " ";
private EditText myEditText;
private String myPreviousText;
...
// Get the views
myEditText = (EditText) v.findViewById(R.id.edt_code);
myEditText.addTextChangedListener(this);
...
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Nothing here
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Nothing here
}
#Override
public void afterTextChanged(Editable s) {
String text = s.toString();
// Only update the EditText when the user modify it -> Otherwise it will be triggered when adding spaces
if (!text.equals(myPreviousText)) {
// Remove spaces
text = text.replace(" ", "");
// Add space between each character
StringBuilder newText = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
if (i == text.length() - 1) {
// Do not add a space after the last character -> Allow user to delete last character
newText.append(Character.toUpperCase(text.charAt(text.length() - 1)));
}
else {
newText.append(Character.toUpperCase(text.charAt(i)) + LETTER_SPACING);
}
}
myPreviousText = newText.toString();
// Update the text with spaces and place the cursor at the end
myEditText.setText(newText);
myEditText.setSelection(newText.length());
}
}
You could implament a custom TextWatcher, and add X spaces every time the user enteres 1.
i have used this, and works for most API levels if not all of them.
KerningViews
Provides a set of views which allows to adjust the spacing between the characters of that view, AKA, Kerning effect.
https://github.com/aritraroy/KerningViews
What's the best way to limit the text length of an EditText in Android?
Is there a way to do this via xml?
Documentation
Example
android:maxLength="10"
use an input filter to limit the max length of a text view.
TextView editEntryView = new TextView(...);
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(8);
editEntryView.setFilters(filterArray);
EditText editText = new EditText(this);
int maxLength = 3;
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
A note to people who are already using a custom input filter and also want to limit the max length:
When you assign input filters in code all previously set input filters are cleared, including one set with android:maxLength. I found this out when attempting to use a custom input filter to prevent the use of some characters that we don't allow in a password field. After setting that filter with setFilters the maxLength was no longer observed. The solution was to set maxLength and my custom filter together programmatically. Something like this:
myEditText.setFilters(new InputFilter[] {
new PasswordCharFilter(), new InputFilter.LengthFilter(20)
});
I have had this problem and I consider we are missing a well explained way of doing this programmatically without losing the already set filters.
Setting the length in XML:
As the accepted answer states correctly, if you want to define a fixed length to an EditText which you won't change further in the future just define in your EditText XML:
android:maxLength="10"
Setting the length programmatically
To set the length programmatically you'll need to set it through an InputFilter. But if you create a new InputFilter and set it to the EditText you will lose all the other already defined filters (e.g. maxLines, inputType, etc) which you might have added either through XML or programatically.
So this is WRONG:
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
To avoid losing previously added filters you need to get those filters, add the new one (maxLength in this case), and set the filters back to the EditText as follow:
Java
InputFilter[] editFilters = editText.getFilters();
InputFilter[] newFilters = new InputFilter[editFilters.length + 1];
System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length);
newFilters[editFilters.length] = new InputFilter.LengthFilter(maxLength);
editText.setFilters(newFilters);
Kotlin however made it easier for everyone, you also need to add the filter to the already existing ones but you can achieve that with a simple:
editText.filters += InputFilter.LengthFilter(maxLength)
TextView tv = new TextView(this);
tv.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(250) });
For anyone else wondering how to achieve this, here is my extended EditText class EditTextNumeric.
.setMaxLength(int) - sets maximum number of digits
.setMaxValue(int) - limit maximum integer value
.setMin(int) - limit minimum integer value
.getValue() - get integer value
import android.content.Context;
import android.text.InputFilter;
import android.text.InputType;
import android.widget.EditText;
public class EditTextNumeric extends EditText {
protected int max_value = Integer.MAX_VALUE;
protected int min_value = Integer.MIN_VALUE;
// constructor
public EditTextNumeric(Context context) {
super(context);
this.setInputType(InputType.TYPE_CLASS_NUMBER);
}
// checks whether the limits are set and corrects them if not within limits
#Override
protected void onTextChanged(CharSequence text, int start, int before, int after) {
if (max_value != Integer.MAX_VALUE) {
try {
if (Integer.parseInt(this.getText().toString()) > max_value) {
// change value and keep cursor position
int selection = this.getSelectionStart();
this.setText(String.valueOf(max_value));
if (selection >= this.getText().toString().length()) {
selection = this.getText().toString().length();
}
this.setSelection(selection);
}
} catch (NumberFormatException exception) {
super.onTextChanged(text, start, before, after);
}
}
if (min_value != Integer.MIN_VALUE) {
try {
if (Integer.parseInt(this.getText().toString()) < min_value) {
// change value and keep cursor position
int selection = this.getSelectionStart();
this.setText(String.valueOf(min_value));
if (selection >= this.getText().toString().length()) {
selection = this.getText().toString().length();
}
this.setSelection(selection);
}
} catch (NumberFormatException exception) {
super.onTextChanged(text, start, before, after);
}
}
super.onTextChanged(text, start, before, after);
}
// set the max number of digits the user can enter
public void setMaxLength(int length) {
InputFilter[] FilterArray = new InputFilter[1];
FilterArray[0] = new InputFilter.LengthFilter(length);
this.setFilters(FilterArray);
}
// set the maximum integer value the user can enter.
// if exeeded, input value will become equal to the set limit
public void setMaxValue(int value) {
max_value = value;
}
// set the minimum integer value the user can enter.
// if entered value is inferior, input value will become equal to the set limit
public void setMinValue(int value) {
min_value = value;
}
// returns integer value or 0 if errorous value
public int getValue() {
try {
return Integer.parseInt(this.getText().toString());
} catch (NumberFormatException exception) {
return 0;
}
}
}
Example usage:
final EditTextNumeric input = new EditTextNumeric(this);
input.setMaxLength(5);
input.setMaxValue(total_pages);
input.setMinValue(1);
All other methods and attributes that apply to EditText, of course work too.
Xml
android:maxLength="10"
Java:
InputFilter[] editFilters = editText.getFilters();
InputFilter[] newFilters = new InputFilter[editFilters.length + 1];
System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length);
newFilters[editFilters.length] = new InputFilter.LengthFilter(maxLength);
editText.setFilters(newFilters);
Kotlin:
editText.filters += InputFilter.LengthFilter(maxLength)
Due to goto10's observation, I put together the following code to protected against loosing other filters with setting the max length:
/**
* This sets the maximum length in characters of an EditText view. Since the
* max length must be done with a filter, this method gets the current
* filters. If there is already a length filter in the view, it will replace
* it, otherwise, it will add the max length filter preserving the other
*
* #param view
* #param length
*/
public static void setMaxLength(EditText view, int length) {
InputFilter curFilters[];
InputFilter.LengthFilter lengthFilter;
int idx;
lengthFilter = new InputFilter.LengthFilter(length);
curFilters = view.getFilters();
if (curFilters != null) {
for (idx = 0; idx < curFilters.length; idx++) {
if (curFilters[idx] instanceof InputFilter.LengthFilter) {
curFilters[idx] = lengthFilter;
return;
}
}
// since the length filter was not part of the list, but
// there are filters, then add the length filter
InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
newFilters[curFilters.length] = lengthFilter;
view.setFilters(newFilters);
} else {
view.setFilters(new InputFilter[] { lengthFilter });
}
}
//Set Length filter. Restricting to 10 characters only
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH)});
//Allowing only upper case characters
editText.setFilters(new InputFilter[]{new InputFilter.AllCaps()});
//Attaching multiple filters
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH), new InputFilter.AllCaps()});
Another way you can achieve this is by adding the following definition to the XML file:
<EditText
android:id="#+id/input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLength="6"
android:hint="#string/hint_gov"
android:layout_weight="1"/>
This will limit the maximum length of the EditText widget to 6 characters.
XML
android:maxLength="10"
Programmatically:
int maxLength = 10;
InputFilter[] filters = new InputFilter[1];
filters[0] = new InputFilter.LengthFilter(maxLength);
yourEditText.setFilters(filters);
Note: internally, EditText & TextView parse the value of android:maxLength in XML and use InputFilter.LengthFilter() to apply it.
See: TextView.java#L1564
From material.io, you can use TextInputEditText combined with TextInputLayout:
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
app:counterMaxLength="1000"
app:passwordToggleEnabled="false">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/edit_text"
android:hint="#string/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="1000"
android:gravity="top|start"
android:inputType="textMultiLine|textNoSuggestions"/>
</com.google.android.material.textfield.TextInputLayout>
You can configure a password EditText with drawable:
Or you can limit text length with/without a counter:
Dependency:
implementation 'com.google.android.material:material:1.1.0-alpha02'
Kotlin:
edit_text.filters += InputFilter.LengthFilter(10)
ZTE Blade A520 has strange effect. When you type more than 10 symbols (for instance, 15), EditText shows first 10, but other 5 are not visible and not accessible. But when you delete symbols with Backspace, it first deletes right 5 symbols and then removes remaining 10. To overcome this behaviour use a solution:
android:inputType="textNoSuggestions|textVisiblePassword"
android:maxLength="10"
or this:
android:inputType="textNoSuggestions"
or this, if you want to have suggestions:
private class EditTextWatcher(private val view: EditText) : TextWatcher {
private var position = 0
private var oldText = ""
override fun afterTextChanged(s: Editable?) = Unit
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
oldText = s?.toString() ?: ""
position = view.selectionStart
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
val newText = s?.toString() ?: ""
if (newText.length > 10) {
with(view) {
setText(oldText)
position = if (start > 0 && count > 2) {
// Text paste in nonempty field.
start
} else {
if (position in 1..10 + 1) {
// Symbol paste in the beginning or middle of the field.
position - 1
} else {
if (start > 0) {
// Adding symbol to the end of the field.
start - 1
} else {
// Text paste in the empty field.
0
}
}
}
setSelection(position)
}
}
}
}
// Usage:
editTextWatcher = EditTextWatcher(view.edit_text)
view.edit_text.addTextChangedListener(editTextWatcher)
This is a custom EditText Class that allow Length filter to live along with other filters.
Thanks to Tim Gallagher's Answer (below)
import android.content.Context;
import android.text.InputFilter;
import android.util.AttributeSet;
import android.widget.EditText;
public class EditTextMultiFiltering extends EditText{
public EditTextMultiFiltering(Context context) {
super(context);
}
public EditTextMultiFiltering(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextMultiFiltering(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setMaxLength(int length) {
InputFilter curFilters[];
InputFilter.LengthFilter lengthFilter;
int idx;
lengthFilter = new InputFilter.LengthFilter(length);
curFilters = this.getFilters();
if (curFilters != null) {
for (idx = 0; idx < curFilters.length; idx++) {
if (curFilters[idx] instanceof InputFilter.LengthFilter) {
curFilters[idx] = lengthFilter;
return;
}
}
// since the length filter was not part of the list, but
// there are filters, then add the length filter
InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
newFilters[curFilters.length] = lengthFilter;
this.setFilters(newFilters);
} else {
this.setFilters(new InputFilter[] { lengthFilter });
}
}
}
it simple way in xml:
android:maxLength="4"
if u require to set 4 character in xml edit-text so,use this
<EditText
android:id="#+id/edtUserCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="4"
android:hint="Enter user code" />
Try this for Java programmatically:
myEditText(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
it simple way in xml:
android:maxLength="#{length}"
for setting it programmatically you can use the following function
public static void setMaxLengthOfEditText(EditText editText, int length) {
InputFilter[] filters = editText.getFilters();
List arrayList = new ArrayList();
int i2 = 0;
if (filters != null && filters.length > 0) {
int filtersSize = filters.length;
int i3 = 0;
while (i2 < filtersSize) {
Object obj = filters[i2];
if (obj instanceof LengthFilter) {
arrayList.add(new LengthFilter(length));
i3 = 1;
} else {
arrayList.add(obj);
}
i2++;
}
i2 = i3;
}
if (i2 == 0) {
arrayList.add(new LengthFilter(length));
}
if (!arrayList.isEmpty()) {
editText.setFilters((InputFilter[]) arrayList.toArray(new InputFilter[arrayList.size()]));
}
}
This works fine...
android:maxLength="10"
this will accept only 10 characters.
I had saw a lot of good solutions, but I'd like to give a what I think as more complete and user-friendly solution, which include:
1, Limit length.
2, If input more, give a callback to trigger your toast.
3, Cursor can be at middle or tail.
4, User can input by paste a string.
5, Always discard overflow input and keep origin.
public class LimitTextWatcher implements TextWatcher {
public interface IF_callback{
void callback(int left);
}
public IF_callback if_callback;
EditText editText;
int maxLength;
int cursorPositionLast;
String textLast;
boolean bypass;
public LimitTextWatcher(EditText editText, int maxLength, IF_callback if_callback) {
this.editText = editText;
this.maxLength = maxLength;
this.if_callback = if_callback;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (bypass) {
bypass = false;
} else {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(s);
textLast = stringBuilder.toString();
this.cursorPositionLast = editText.getSelectionStart();
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
if (s.toString().length() > maxLength) {
int left = maxLength - s.toString().length();
bypass = true;
s.clear();
bypass = true;
s.append(textLast);
editText.setSelection(this.cursorPositionLast);
if (if_callback != null) {
if_callback.callback(left);
}
}
}
}
edit_text.addTextChangedListener(new LimitTextWatcher(edit_text, MAX_LENGTH, new LimitTextWatcher.IF_callback() {
#Override
public void callback(int left) {
if(left <= 0) {
Toast.makeText(MainActivity.this, "input is full", Toast.LENGTH_SHORT).show();
}
}
}));
What I failed to do is, if user highlight a part of the current input and try to paste an very long string, I don't know how to restore the highlight.
Such as, max length is set to 10, user inputed '12345678', and mark '345' as highlight, and try to paste a string of '0000' which will exceed limitation.
When I try to use edit_text.setSelection(start=2, end=4) to restore origin status, the result is, it just insert 2 space as '12 345 678', not the origin highlight. I'd like someone solve that.
You can use android:maxLength="10" in the EditText.(Here the limit is upto 10 characters)
I was using "maxLength" but it didn't work for me. So, based on my experience, I tried a few things.
And I detected the problem.
I must declare the id.
Then:
android:id="#+id/editTextTest"
android:maxLength="10"