Here is my setup
<EditText
android:id="#+id/inputNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="#string/inputHintText"
android:inputType="textCapCharacters"
android:maxLength="10"
android:textColor="#383838" />
and here is the java code
final EditText inputNo = (EditText)findViewById(R.id.inputNo);
inputNo.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
#Override
public void afterTextChanged(Editable s)
{
if (s.length() > 2)
{
if (!s.toString().startsWith("ABCD"))
{
inputNo.setError( "Must start with ABCD" );
}
}
}
});
The code works fine and shows the red error message in the text box until keystroke 10. But lets say if the user still hits 11th key on the textbox then the error is going away and not staying on the textbox.
One thing I realized that after the 10th input char is entered the afterTextChanged() method is not invoked meaning the addTextChangedListener is not really listening to input keys after the 10th chars because we have defined android:maxLength="10" in EditText.
How to resolve this? My desired result is that if the input do not start with "ABCD" then the error message stays on the edittext field until the user corrects it.
Any pointers/help appreciated!
Try this to limit EditText input:
TextView editEntryVew = new TextView(...);
InputFilter[] filterArray = new InputFilter[1];
FilterArray[0] = new InputFilter.LengthFilter(10);
editEntryView.setFilters(filterArray );
Make sure you handle the delete key being pressed while the EditText is empty: https://stackoverflow.com/a/13983097/832776
The problem happens when users input more texts than "maxLength" or delete an empty field. It seems to be an OS bug, I tried many ways and ended up with a workaround as below:
Suppose you have many textfields and a submit button, when users press submit, reset these textfields with their own texts to trigger validation again, such as:
textField1.setText(textField1.getText())
textField2.setText(textField2.getText())
if (TextUtils.isEmpty(textField1.getError()) && TextUtils.isEmpty(textField2.getError()))
// submit
else
Toast.makeText(mContext, "Please correct invalid fields", Toast.LENGTH_SHORT).show();
I hope this helps
Related
I have been having issues with some odd behaviours from the EditText .setSelection that I am hoping you can all help with!
The app I am working on has a search field and there is the need to have it behave very similar to a browser search bar. For example, if the user types "fo", we would want the EditText to autocomplete to "foobar" with the autocompleted "obar" text highlighted so it can be easily replaced by the user incase the autocomplete does not match what the user was intending to type.
To accomplish this, I have an EditText field with a TextWatcher setup to try to autocomplete the text afterTextChanged. The following is my code:
editText.addTextChangedListener(new TextWatcher() {
int lastCount = 0;
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable editable) {
editText.removeTextChangedListener(this);
String searchString = editable.toString();
if (editable.length() > lastCount) {
lastCount = editable.length();
int oldLength = searchString.length();
String autoFillResult = completeAutofill(searchString);
if (!autoFillResult.equals("")) {
searchString = autoFillResult;
editable.clear();
editable.append(autoFillResult);
editText.setSelection(oldLength, autoFillResult.length());
}
} else lastCount = editable.length();
editText.addTextChangedListener(this);
}
});
My issue is as follows. Using the previous "Foobar" case:
The user types "F", the EditText autofills "oobar" and highlights it.
Then the user types the first "o"
The EditText field is momentarily cleared (i.e. afterTextChanged receives an Editable with the empty string)
The EditText correctly autofills to user supplied "Fo" followed by autocompleted "obar" which is highlighted.
The issue is the EditText is being cleared then repopulated when the user types the next character, which creates a noticeable disturbance in the EditText field. Interestingly, I have singled out the editText.setSelection(oldLength, autoFillResult.length()); as the culprit (i.e. commenting out the line gets rid of the issue, but obviously its the wrong functionality).
After completing some Google research and my own debugging I am still unsure why this is happening. The issue does not appear excessively common as I could not find it on Google and I could not figure out the reason for this issue in my own experimentation.
Thank you in advance!
the if condition should possibly be:
autoFillResult != null && !autoFillResult.equals("")
while you might be looking for (or attempting to recreate) an AutoCompleteTextView.
Try removing editable.clear();
This code is in a layout file.
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textInputLayoutMobile"
>
<EditText
android:inputType="number"
android:id="#+id/mobileNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="10"
android:hint="Mobile Number" />
</android.support.design.widget.TextInputLayout>
This is Java code.
TextInputLayout textInputLayoutMobile = (TextInputLayout)findViewById(R.id.textInputLayoutMobile);
textInputLayoutMobile.setErrorEnabled(true);
textInputLayoutMobile.setError("This field is required");
Current behaviour: When we click on the field, it shows, "This field is required". Also when we start typing in the field, this message does not go away.
Desired behaviour: When we click for the first time, it should not show, "This field is required". When we move to another field after touching this field and without entering any data, it should show, "This field is required". Also when we start typing in the field, this message should go away.
I think you must use text change listener
edit.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) {
//set error
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
and on his method to set your desire output.. hope to help you!
I believe the error is that those two lines of code are used while retrieving the textInputLayoutMobile from your layout (probably in onCreate). So the view is set to always display this error message.
textInputLayoutMobile.setErrorEnabled(true);
textInputLayoutMobile.setError("This field is required");
I suppose those two lines should be moved from this point and set there where you should validate the textInputLayoutMobile input and deciding that the validation is wrong, e.g. in an onClick callback or listener. Additionally when your input is validated to true then set textInputLayoutMobile.setErrorEnabled(false);
See an example here: http://code.tutsplus.com/tutorials/creating-a-login-screen-using-textinputlayout--cms-24168
I think you need take id="#+id/mobileNumber", set the widget and than try something like that
your_widget.setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
if (yourwidget.getText().toString().length() == 0) {
yourwidget.setError("This field is required");}
else etc...
You could use this control on a "next" button or something like that (save button etc) insted of use that on the field directly (sorry for my english)
I think you need to take the reference of EditText and not the TextInputLayout.
Try
EditText editText = (EditText)findViewById(R.id.mobileNumber);
editText.setError("This field is required");
Hi I am learning Android programming and have run into an issue that I couldn't get a clear answer to through researching.
I have a TextView which serves as a label for my EditText. I have a method which checks if the EditText is an empty String. If the string is empty I want to be able to get a reference to the TextView that corresponds to that EditText in order to make a toast saying something like "please enter a value for ".
I've looked into getLabelFor/setLabelFor but is there a way to do this in the layout XML?
What is best practice for this type of functionality.
You're describing a functionally that is build in to EditText. There is a special field you can define in xml called hint, which is the recommended way to label an EditText rather than a nearby TextView. Additionally, EditText has a method called setError() (link). If the user attempts to hit a submit button, for example, you can check to see if the EditText is empty and if so, call setError().
I wonder if the following is the thing that you need
TextWatcher inputTextWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after){
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().equals("")) {
textView.setText("please enter a value for ..");
} else {
textView.setText("<the textedit is not empty>");
}
}
public void afterTextChanged(Editable s) {
}
};
editText.addTextChangedListener(inputTextWatcher);
I am building a simple chat app where the user has the ability to send text and emoticons. I can send both text and emoticons to another phone. My problems are:
1.When I type something and add an emoticon:
Then I cannot type any text right before and right after the image. I can write before the "o" letter. The system "sees" that I type, so even if I type "Honey" after the smiley, I cannot see it, but the EditText registers it and the message is sent:
2.When I add just an emoticon to the Edittext then I delete it, I cannot type anything because the deleted emoticon appears. It appears only once, so no matter how many characters I type, the EditText looks like just before I deleted the emoticon, BUT the text is sent without the emoticon, just like in all three cases.
3.When I type "something" in the EditText then insert an emoticon after "some":
Then I put the cursor after the emoticon and delete it, here what's left:
But the correct message is sent when I press the Send button:
That's what's inside the button listener of the emoticon (this method is activated when I click the emoticon to add it to the EditText).
ib_happy.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int cursorPosition = mOutEditText.getSelectionStart();
mOutEditText.getText().insert(cursorPosition, smileys[0]);
SpannableStringBuilder ssb = new SpannableStringBuilder(mOutEditText.getText());
ssb.setSpan(new ImageSpan(bitmapArray.get(0), ImageSpan.ALIGN_BASELINE), cursorPosition, cursorPosition+2, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
mOutEditText.setText(ssb, BufferType.SPANNABLE);
mOutEditText.setSelection(cursorPosition+2);
dialog_emoticon.dismiss();
}
});
I found the solution. All I had to do was to change Spannable.SPAN_INCLUSIVE_INCLUSIVE to Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
I would add a textwatcher to that edittext and watch as the user types, that way I can reposition the images/set the text/make corrections/validate input/etc.
editText.addTextChangedListener(textWatcher);
textWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
//editText.doStuffHere
//reposition your image/etc.
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
public void onTextChanged(CharSequence s, int start, int before, int count) { }
};
I need to implement an edittext field that just allows user input from 20 to 60. If user input a number that is out of range, a dialog will display and force user to input again.
So the text watcher is not useful because it cannot prevent user input a number that lower than 20.
The onFocusChangedListener is neither, if user clicks on 'done' button, the edittext doesn't lost focus, so the trigger doesn't fire as well.
Besides, the edittext is inside a tab view, so when user clicks on another tab, the trigger fires but user cannot input value for that edittext any more.
Alvin is right ... this is my code to do something with text once entered, but could have as easily been a validation sequence:
smsMsgBody_editText.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Do something fancy
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
public void afterTextChanged(Editable s) { }
});
How about keeping track of the EditText field with onTextChanged?
use these
android:maxLength="2" android:numeric="integer"
then when you get the number like: number.gettext() you make validations like if number>60 and lower then 20 you can do number.setHint("number no valid");