Been stuck on this all night and there just doesn't seem to be an easy solution to it. I'm trying to validate all 4 of my fields to ensure that there is a value in each one of them, if there's a value in each one of them after I click the Calculate button a total will be calculated. If any of them don't have a value in them it'll return an error at every EditText which doesn't have a value and a total will not be calculated.
cal.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
if( eLoan.getText().toString().length() == 0 )
{
eLoan.setError( "A value is required" );
}
else if( eWage.getText().toString().length() == 0 )
{
eWage.setError( "A value is required" );
}
else if( eGrant.getText().toString().length() == 0 )
{
eGrant.setError( "A value is required" );
}
else if( eOther.getText().toString().length() == 0 )
{
eOther.setError( "A value is required" );
}
else
convertToString();
converToDouble();
inTotal = inLoan + inWage + inGrant + inOther;
DecimalFormat currency = new DecimalFormat(".00");
TotalInNum.setText("£" + currency.format(inTotal));
}
});
I can't get my head around it, I've tried to incorporate a boolean statement to check each EditText but it didn't work either. I'm convinced there's an easier method to do this.
I'm quite new to android, self teaching myself it so I would appreciate it if people could advise me on what I'm doing wrong and maybe give me an example of what I should do.
Thanks to all who respond.
Just to build on what others have said. You can do something like this...
Make a validation method that loops through your EditTexts, checks if they're empty, if true set error and then returns true or false...
public boolean validateEditText(int[] ids)
{
boolean isEmpty = false;
for(int id: ids)
{
EditText et = (EditText)findViewById(id);
if(TextUtils.isEmpty(et.getText().toString()))
{
et.setError("Must enter Value");
isEmpty = true;
}
}
return isEmpty;
}
Make a list of you EditText id's..
int[] ids = new int[]
{
R.id.section1_item1_textfield,
R.id.section1_item2_textfield,
R.id.section1_item3_textfield
};
Now use your validation method to check if empty...
if(!validateEditText(ids))
{
//if not empty do something
}else{
//if empty do somethingelse
}
To use the method above you will need to...
import android.text.TextUtils;
The good thing about doing it this way is that you can simply chuck all of your EditTexts into the list and it does the rest for you. Maintaining a huge chunk of if statements can be annoying and time consuming.
I think the problem is you're missing curlies at the last else, where the logic sits. As it is right now, only convertToString(); is part of that last else and the last four statements will execute no matter what error you're setting.
Try this:
cal.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
boolean failFlag = false;
// TODO Auto-generated method stub
if( eLoan.getText().toString().trim().length() == 0 )
{
failFlag = true;
eLoan.setError( "A value is required" );
}
if( eWage.getText().toString().trim().length() == 0 )
{
failFlag = true;
eWage.setError( "A value is required" );
}
if( eGrant.getText().toString().trim().length() == 0 )
{
failFlag = true;
eGrant.setError( "A value is required" );
}
if( eOther.getText().toString().trim().length() == 0 )
{
failFlag = true;
eOther.setError( "A value is required" );
}
// if all are fine
if (failFlag == false) {
convertToString();
converToDouble();
inTotal = inLoan + inWage + inGrant + inOther;
DecimalFormat currency = new DecimalFormat(".00");
TotalInNum.setText("£" + currency.format(inTotal));
}
}
});
This code will set more than one error, if more exist. Yours will signal only the first found error.
I think the best way to solve this problem is the example below:
private boolean verifyIfEditTextIsFilled(EditText... editText) {
boolean result = true;
for (EditText text : editText) {
if (text.getText().toString().isEmpty()) {
final View focusView = text;
text.setError(getString(R.string.error_required));
focusView.requestFocus();
result = false;
}
}
return result;
}
late answer But may Help someone in need.
Simplest way -->
Create method as below
public Boolean validateUserInput()
{
Boolean isAnyFieldsEmpty=false;
if (position.getText().toString()==null || position.getText().toString().equalsIgnoreCase(""))
{
position.setError("Empty postion");
isAnyFieldsEmpty=true;
}
else{
position.setError(null);
isAnyFieldsEmpty=false;
}
if (eligiblity.getText().toString()==null || eligiblity.getText().toString().equalsIgnoreCase(""))
{
eligiblity.setError("Empty postion");
isAnyFieldsEmpty=true;
}
else{
eligiblity.setError(null);
isAnyFieldsEmpty=false;
}
if (skillsRequired.getText().toString()==null || skillsRequired.getText().toString().equalsIgnoreCase(""))
{
skillsRequired.setError("Empty postion");
isAnyFieldsEmpty=true;
}
else{
skillsRequired.setError(null);
isAnyFieldsEmpty=false;
}
if (desc.getText().toString()==null || desc.getText().toString().equalsIgnoreCase(""))
{
desc.setError("Empty postion");
isAnyFieldsEmpty=true;
}
else{
desc.setError(null);
isAnyFieldsEmpty=false;
}
if (interviewFrmDate.getText().toString()==null || interviewFrmDate.getText().toString().equalsIgnoreCase(""))
{
interviewFrmDate.setError("choose date");
isAnyFieldsEmpty=true;
}else{
interviewFrmDate.setError(null);
isAnyFieldsEmpty=false;
}
if (interviewToDate.getText().toString()==null || interviewToDate.getText().toString().equalsIgnoreCase(""))
{
interviewToDate.setError("choose date");
isAnyFieldsEmpty=true;
}else{
interviewToDate.setError(null);
isAnyFieldsEmpty=false;
}
if (interviewToTime.getText().toString()==null || interviewToTime.getText().toString().equalsIgnoreCase(""))
{
interviewToTime.setError("choose date");
isAnyFieldsEmpty=true;
}else{
interviewToTime.setError(null);
isAnyFieldsEmpty=false;
}
return isAnyFieldsEmpty;
}
Now on your Button click
call that method as below and validate
#overide
public void onclick
{
Boolean isinputEmpty=validateUserInput()
if(isinputEmpty==false)
{
///process your save or whatever processing it is
}
}
Related
I'm trying to check if a string is alphanumeric or not. I tried many things given in other posts but to no avail. I tried StringUtils.isAlphanumeric(), a library from Apache Commons but failed. I tried regex also from this link but that too didn't worked. Is there a method to check if a string is alphanumeric and returns true or false according to it?
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String text = fullnameet.getText().toString();
String numRegex = ".*[0-9].*";
String alphaRegex = ".*[A-Z].*";
if (text.matches(numRegex) && text.matches(alphaRegex)) {
System.out.println("Its Alphanumeric");
}else{
System.out.println("Its NOT Alphanumeric");
}
}
});
If you want to ascertain that your string is both alphanumeric and contains both numbers and letters, then you can use the following logic:
.*[A-Za-z].* check for the presence of at least one letter
.*[0-9].* check for the presence of at least one number
[A-Za-z0-9]* check that only numbers and letters compose this string
String text = fullnameet.getText().toString();
if (text.matches(".*[A-Za-z].*") && text.matches(".*[0-9].*") && text.matches("[A-Za-z0-9]*")) {
System.out.println("Its Alphanumeric");
} else {
System.out.println("Its NOT Alphanumeric");
}
Note that we could handle this with a single regex but it would likely be verbose and possibly harder to maintain than the above answer.
Original from here
String myString = "qwerty123456";
System.out.println(myString.matches("[A-Za-z0-9]+"));
String myString = "qwerty123456";
if(myString.matches("[A-Za-z0-9]+"))
{
System.out.println("Alphanumeric");
}
if(myString.matches("[A-Za-z]+"))
{
System.out.println("Alphabet");
}
try this
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Pattern p = Pattern.compile("[^a-zA-Z0-9]");
boolean hasSpecialChar = p.matcher(edittext.getText().toString()).find();
if (!edittext.getText().toString().trim().equals("")) {
if (hasSpecialChar) {
Toast.makeText(MainActivity.this, "not Alphanumeric", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Its Alphanumeric", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(MainActivity.this, "Empty value of edit text", Toast.LENGTH_SHORT).show();
}
}
});
This is the code to check if the string is alphanumeric or not. For more details check Fastest way to check a string is alphanumeric in Java
public class QuickTest extends TestCase {
private final int reps = 1000000;
public void testRegexp() {
for(int i = 0; i < reps; i++)
("ab4r3rgf"+i).matches("[a-zA-Z0-9]");
}
public void testIsAlphanumeric2() {
for(int i = 0; i < reps; i++)
isAlphanumeric2("ab4r3rgf"+i);
}
public boolean isAlphanumeric2(String str) {
for (int i=0; i<str.length(); i++) {
char c = str.charAt(i);
if (c < 0x30 || (c >= 0x3a && c <= 0x40) || (c > 0x5a && c <= 0x60) || c > 0x7a)
return false;
}
return true;
}
}
While there are many ways to skin this cat, I prefer to wrap such code into reusable extension methods that make it trivial to do going forward. When using extension methods, you can also avoid RegEx as it is slower than a direct character check. I like using the extensions in the Extensions.cs NuGet package. It makes this check as simple as:
Add the https://www.nuget.org/packages/Extensions.cs package to your project.
Add "using Extensions;" to the top of your code.
"smith23#".IsAlphaNumeric() will return False whereas "smith23".IsAlphaNumeric() will return True. By default the .IsAlphaNumeric() method ignores spaces, but it can also be overridden such that "smith 23".IsAlphaNumeric(false) will return False since the space is not considered part of the alphabet.
Every other check in the rest of the code is simply MyString.IsAlphaNumeric().
Your example code would become as simple as:
using Extensions;
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String text = fullnameet.getText().toString();
//String numRegex = ".*[0-9].*";
//String alphaRegex = ".*[A-Z].*";
//if (text.matches(numRegex) && text.matches(alphaRegex)) {
if (text.IsAlphaNumeric()) {
System.out.println("Its Alphanumeric");
}else{
System.out.println("Its NOT Alphanumeric");
}
}
});
I have write a method for register users for backendless. With filled all text fields I can register users. My problem is when when I click button with empty text fields app getting crash, but I wrote a if statement for check empty text fields and show a toast.
public void RegisterButtonPressed(View view) {
if(email.getText() == null || password.getText() == null || username.getText() == null){
Toast.makeText(this, "Every Fileds should be filled", Toast.LENGTH_SHORT).show();
} else {
if(email.getText() != null && password.getText() != null && username.getText() != null) {
final String emailS = email.getText().toString();
final String passwordS = password.getText().toString();
String usernameS = username.getText().toString();
BackendlessUser user = new BackendlessUser();
user.setEmail(emailS);
user.setPassword(passwordS);
user.setProperty("name",usernameS);
user.setProperty("Avatar","");
Backendless.UserService.register(user, new AsyncCallback<BackendlessUser>() {
#Override
public void handleResponse(BackendlessUser backendlessUser) {
Toast.makeText(RegisterActivity.this, "User Registration Successfull", Toast.LENGTH_SHORT).show();
Backendless.UserService.login(emailS, passwordS, new AsyncCallback<BackendlessUser>() {
#Override
public void handleResponse(BackendlessUser backendlessUser) {
Toast.makeText(RegisterActivity.this, "Logged", Toast.LENGTH_SHORT).show();
}
#Override
public void handleFault(BackendlessFault backendlessFault) {
Toast.makeText(RegisterActivity.this, "User Login Unsuccessfull: " + backendlessFault.getDetail(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void handleFault(BackendlessFault backendlessFault) {
Toast.makeText(RegisterActivity.this, "User Registration Unsuccesful: " + backendlessFault.getDetail(), Toast.LENGTH_SHORT).show();
}
});
}
}
}
error log
you should check with
if(TextUtils.isEmpty(email.getText()))
instead of
if (email.getText() == null)
From my experience, the getText() was not return null if it empty, but empty string a.k.a ""
TextUtils.isEmpty() however, will check both null and "" as empty string
You're only checking if the string is null. If it's empty, your if statement will not catch that and could still cause a crash. You should be checking for empty string as well.
if(email.getText() == null || email.getText().length() == 0 ||
password.getText() == null || password.getText.length() == 0 ||
username.getText() == null || username.getText.length() == 0){
Toast.makeText(this, "Every Fileds should be filled", Toast.LENGTH_SHORT).show();
}
This happened with me on AppCompatAutoCompleteTextView, where I have added Spinner Adapter with Filterable.
I have overrided the AppCompatAutoCompleteTextView enoughToFilter() method.
#Override
public boolean enoughToFilter() {
return showAlways || super.enoughToFilter();
}
showAlways is a bool object where I was setting apply a filter with threshold.
As enoughToFilter () => Returns true if the amount of text in the field meets or exceeds the getThreshold() requirement.
On zero-length it was crashing when this showAlways is set to false, just make it to true or
set threshold to 0 & set showAlways to false.
I have a method where i compare two string, but they dont compare the right way. For example I have this:
dropdown.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
String selectedRate = data[i];
if (!data[i].equals("")) {
showSubQuestion(selectedRate);
} else {
selectedRate = "";
}
where data[i] is also and string and then it continues to:
showSubQuestion(String selectedValue){
...
String selectedValueId = selectedValue;
if (selectedValueId.equals("2459") && selectedValueId.equals("2460")) {
surveyArray[0].getQuestions()[i].getQuestion_order_id().equals("2");
myTextViews[j].setText(surveyArray[0].getQuestions()[1].getText());
}
if (selectedValueId.equals("2461") && selectedValueId.equals("2462")) {
surveyArray[0].getQuestions()[i].getQuestion_order_id().equals("3");
myTextViews[j].setText(surveyArray[0].getQuestions()[2].getText());
} else {
surveyArray[0].getQuestions()[i].getQuestion_order_id().equals("4");
myTextViews[j].setText(surveyArray[0].getQuestions()[3].getText());
}
}
where selected value is ex: 2461 but it doesnt enters i the secont IF.
What am I doing wrong?
Here's part of the JSON:
"question_choices":[
{
"id":2459,
"label":"10 - highly likely",
"value":"10"
},
{
"id":2460,
"label":"9",
"value":"9"
},
{
"id":2461,
"label":"8",
"value":"8"
String selectedValueId = selectedValue;
if (selectedValueId.equals("2459") || selectedValueId.equals("2460")) {
surveyArray[0].getQuestions()[i].getQuestion_order_id().equals("2");
myTextViews[j].setText(surveyArray[0].getQuestions()[1].getText());
}
if (selectedValueId.equals("2461") || selectedValueId.equals("2462")) {
surveyArray[0].getQuestions()[i].getQuestion_order_id().equals("3");
myTextViews[j].setText(surveyArray[0].getQuestions()[2].getText());
} else {
surveyArray[0].getQuestions()[i].getQuestion_order_id().equals("4");
myTextViews[j].setText(surveyArray[0].getQuestions()[3].getText());
}
}
Replace this code & Try this out it will work
Your conditions are incorrect
if (selectedValueId.equals("2461") && selectedValueId.equals("2462"))
you should replace && with ||
Your value can't be 2461 AND 2462 at the same time
May be you want to use || instead of &&
I have a registration form in my application which I am trying to validate. I'm facing some problems with my validation while validating the phone number and email fields.
Here is my code:
private boolean validate() {
String MobilePattern = "[0-9]{10}";
//String email1 = email.getText().toString().trim();
String emailPattern = "[a-zA-Z0-9._-]+#[a-z]+\\.+[a-z]+";
if (name.length() > 25) {
Toast.makeText(getApplicationContext(), "pls enter less the 25 character in user name", Toast.LENGTH_SHORT).show();
return true;
} else if (name.length() == 0 || number.length() == 0 || email.length() ==
0 || subject.length() == 0 || message.length() == 0) {
Toast.makeText(getApplicationContext(), "pls fill the empty fields", Toast.LENGTH_SHORT).show();
return false;
} else if (email.getText().toString().matches(emailPattern)) {
//Toast.makeText(getApplicationContext(),"valid email address",Toast.LENGTH_SHORT).show();
return true;
} else if(!email.getText().toString().matches(emailPattern)) {
Toast.makeText(getApplicationContext(),"Please Enter Valid Email Address",Toast.LENGTH_SHORT).show();
return false;
} else if(number.getText().toString().matches(MobilePattern)) {
Toast.makeText(getApplicationContext(), "phone number is valid", Toast.LENGTH_SHORT).show();
return true;
} else if(!number.getText().toString().matches(MobilePattern)) {
Toast.makeText(getApplicationContext(), "Please enter valid 10 digit phone number", Toast.LENGTH_SHORT).show();
return false;
}
return false;
}
I have used this code above for the validation. The problem I'm facing is in the phone number and email validation, only one validation is working. For example, if I comment out the phone number validation, the email validation is working properly. If I comment out the email validation, the phone number validation is working. If use both validations, it's not working.
For Email Address Validation
private boolean isValidMail(String email) {
String EMAIL_STRING = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*#"
+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
return Pattern.compile(EMAIL_STRING).matcher(email).matches();
}
OR
private boolean isValidMail(String email) {
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
}
For Mobile Validation
For Valid Mobile You need to consider 7 digit to 13 digit because some country have 7 digit mobile number. If your main target is your own country then you can match with the length. Assuming India has 10 digit mobile number. Also we can not check like mobile number must starts with 9 or 8 or anything.
For mobile number I used this two Function:
private boolean isValidMobile(String phone) {
if(!Pattern.matches("[a-zA-Z]+", phone)) {
return phone.length() > 6 && phone.length() <= 13;
}
return false;
}
OR
private boolean isValidMobile(String phone) {
return android.util.Patterns.PHONE.matcher(phone).matches();
}
Use Pattern package in Android to match the input validation for email and phone
Do like
android.util.Patterns.EMAIL_ADDRESS.matcher(input).matches();
android.util.Patterns.PHONE.matcher(input).matches();
Android has build-in patterns for email, phone number, etc, that you can use if you are building for Android API level 8 and above.
private boolean isValidEmail(CharSequence email) {
if (!TextUtils.isEmpty(email)) {
return Patterns.EMAIL_ADDRESS.matcher(email).matches();
}
return false;
}
private boolean isValidPhoneNumber(CharSequence phoneNumber) {
if (!TextUtils.isEmpty(phoneNumber)) {
return Patterns.PHONE.matcher(phoneNumber).matches();
}
return false;
}
Try this
public class Validation {
public final static boolean isValidEmail(CharSequence target) {
if (target == null) {
return false;
} else {
return android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
}
}
public static final boolean isValidPhoneNumber(CharSequence target) {
if (target.length()!=10) {
return false;
} else {
return android.util.Patterns.PHONE.matcher(target).matches();
}
}
}
He want an elegant and proper solution try this small regex pattern matcher.
This is specifically for India.(First digit can't be zero and and then can be any 9 digits)
return mobile.matches("[1-9][0-9]{9}");
Pattern Breakdown:-
[1-9] matches first digit and checks if number(integer) lies between(inclusive) 1 to 9
[0-9]{9} matches the same thing but {9} tells the pattern that it has to check for upcoming all 9 digits.
Now the {9} part may vary for different countries so you may have array which tells the number of digits allowed in phone number. Some countries also have significance for zero ahead of number, so you may have exception for those and design a separate regex patterns for those countries phone numbers.
in Kotlin you can use Extension function to validate input
// for Email validation
fun String.isValidEmail(): Boolean =
this.isNotEmpty() && Patterns.EMAIL_ADDRESS.matcher(this).matches()
// for Phone validation
fun String.isValidMobile(phone: String): Boolean {
return Patterns.PHONE.matcher(phone).matches()
}
try this:
extMobileNo.addTextChangedListener(new MyTextWatcher(extMobileNo));
private boolean validateMobile() {
String mobile =extMobileNo.getText().toString().trim();
if(mobile.isEmpty()||!isValidMobile(mobile)||extMobileNo.getText().toString().toString().length()<10 || mobile.length()>13 )
{
inputLayoutMobile.setError(getString(R.string.err_msg_mobile));
requestFocus(extMobileNo);
return false;
}
else {
inputLayoutMobile.setErrorEnabled(false);
}
return true;
}
private static boolean isValidMobile(String mobile)
{
return !TextUtils.isEmpty(mobile)&& Patterns.PHONE.matcher(mobile).matches();
}
The built in PHONE pattern matcher does not work in all cases.
So far, this is the best solution I have found to validate a phone number (code in Kotlin, extension of String)
fun String.isValidPhoneNumber() : Boolean {
val patterns = "^\\s*(?:\\+?(\\d{1,3}))?[-. (]*(\\d{3})[-. )]*(\\d{3})[-. ]*(\\d{4})(?: *x(\\d+))?\\s*$"
return Pattern.compile(patterns).matcher(this).matches()
}
//validation class
public class EditTextValidation {
public static boolean isValidText(CharSequence target) {
return target != null && target.length() != 0;
}
public static boolean isValidEmail(CharSequence target) {
if (target == null) {
return false;
} else {
return android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
}
}
public static boolean isValidPhoneNumber(CharSequence target) {
if (target.length() != 10) {
return false;
} else {
return android.util.Patterns.PHONE.matcher(target).matches();
}
}
//activity or fragment
val userName = registerNameET.text?.trim().toString()
val mobileNo = registerMobileET.text?.trim().toString()
val emailID = registerEmailIDET.text?.trim().toString()
when {
!EditTextValidation.isValidText(userName) -> registerNameET.error = "Please provide name"
!EditTextValidation.isValidEmail(emailID) -> registerEmailIDET.error =
"Please provide email"
!EditTextValidation.isValidPhoneNumber(mobileNo) -> registerMobileET.error =
"Please provide mobile number"
else -> {
showToast("Hello World")
}
}
**Hope it will work for you... It is a working example.
I am always using this methode for Email Validation:
public boolean checkForEmail(Context c, EditText edit) {
String str = edit.getText().toString();
if (android.util.Patterns.EMAIL_ADDRESS.matcher(str).matches()) {
return true;
}
Toast.makeText(c, "Email is not valid...", Toast.LENGTH_LONG).show();
return false;
}
public boolean checkForEmail() {
Context c;
EditText mEtEmail=(EditText)findViewById(R.id.etEmail);
String mStrEmail = mEtEmail.getText().toString();
if (android.util.Patterns.EMAIL_ADDRESS.matcher(mStrEmail).matches()) {
return true;
}
Toast.makeText(this,"Email is not valid", Toast.LENGTH_LONG).show();
return false;
}
public boolean checkForMobile() {
Context c;
EditText mEtMobile=(EditText)findViewById(R.id.etMobile);
String mStrMobile = mEtMobile.getText().toString();
if (android.util.Patterns.PHONE.matcher(mStrMobile).matches()) {
return true;
}
Toast.makeText(this,"Phone No is not valid", Toast.LENGTH_LONG).show();
return false;
}
For check email and phone number you need to do that
public static boolean isValidMobile(String phone) {
boolean check = false;
if (!Pattern.matches("[a-zA-Z]+", phone)) {
if (phone.length() < 9 || phone.length() > 13) {
// if(phone.length() != 10) {
check = false;
// txtPhone.setError("Not Valid Number");
} else {
check = android.util.Patterns.PHONE.matcher(phone).matches();
}
} else {
check = false;
}
return check;
}
public static boolean isEmailValid(String email) {
boolean check;
Pattern p;
Matcher m;
String EMAIL_STRING = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*#"
+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
p = Pattern.compile(EMAIL_STRING);
m = p.matcher(email);
check = m.matches();
return check;
}
String enter_mob_or_email="";//1234567890 or test#gmail.com
if (isValidMobile(enter_mob_or_email)) {// Phone number is valid
}else isEmailValid(enter_mob_or_email){//Email is valid
}else{// Not valid email or phone number
}
XML
<android.support.v7.widget.AppCompatEditText
android:id="#+id/et_email_contact"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:maxLines="1"
android:hint="Enter Email or Phone Number"/>
Java
private AppCompatEditText et_email_contact;
private boolean validEmail = false, validPhone = false;
et_email_contact = findViewById(R.id.et_email_contact);
et_email_contact.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) {
String regex = "^[+]?[0-9]{10,13}$";
String emailContact = s.toString();
if (TextUtils.isEmpty(emailContact)) {
Log.e("Validation", "Enter Mobile No or Email");
} else {
if (emailContact.matches(regex)) {
Log.e("Validation", "Valid Mobile No");
validPhone = true;
validEmail = false;
} else if (Patterns.EMAIL_ADDRESS.matcher(emailContact).matches()) {
Log.e("Validation", "Valid Email Address");
validPhone = false;
validEmail = true;
} else {
validPhone = false;
validEmail = false;
Log.e("Validation", "Invalid Mobile No or Email");
}
}
}
});
if (validPhone || validEmail) {
Toast.makeText(this, "Valid Email or Phone no", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "InValid Email or Phone no", Toast.LENGTH_SHORT).show();
}
private fun isValidMobileNumber(s: String): Boolean {
// 1) Begins with 0 or 91
// 2) Then contains 6 or 7 or 8 or 9.
// 3) Then contains 9 digits
val p: Pattern = Pattern.compile("(0|91)?[6-9][0-9]{9}")
// Pattern class contains matcher() method
// to find matching between given number
val m: Matcher = p.matcher(s)
return m.find() && m.group().equals(s)
}
I want to be able to calculate something depending on the input in 2 of 3 EditText. For Example: I make an input in ET 1 and 2 -> i get a calculation in ET 3. ET 1 and 3 -> calculation in ET 2... and so on.
I get it to work with 2 EditText but with 3 I get an StackOverFlowError.
private class GenericTextWatcher implements TextWatcher {
private View view;
private GenericTextWatcher(View view) {
this.view = view;
}
public void beforeTextChanged(CharSequence charSequence, int i, int i1,
int i2) {
}
public void onTextChanged(CharSequence charSequence, int i, int i1,
int i2) {
}
public void afterTextChanged(Editable editable) {
switch (view.getId()) {
case R.id.liter_input:
try {
if (amount_widget.getText().toString().equals(" ") == false
|| literPrice_widget.getText().toString()
.equals(" ") == false
|| price_widget.getText().toString().equals(" ") == false) {
double editTextCalc = Double.parseDouble(amount_widget
.getText().toString())
* Double.parseDouble(literPrice_widget
.getText().toString());
editTextCalc = Math.round(editTextCalc * 100) / 100.0;
price_widget.setText(String.valueOf(decimalFormat
.format(editTextCalc)));
}
} catch (Exception e) {
// TODO: handle exception
}
break;
case R.id.literprice_input:
try {
if (amount_widget.getText().toString().equals(" ") == false
|| literPrice_widget.getText().toString()
.equals(" ") == false
|| price_widget.getText().toString().equals(" ") == false) {
double editTextCalc = Double.parseDouble(amount_widget
.getText().toString())
* Double.parseDouble(literPrice_widget
.getText().toString());
editTextCalc = Math.round(editTextCalc * 100) / 100.0;
price_widget.setText(String.valueOf(decimalFormat
.format(editTextCalc)));
}
} catch (Exception e) {
// TODO: handle exception
}
break;
case R.id.price_input:
try {
if (amount_widget.getText().toString().equals(" ") == false
|| literPrice_widget.getText().toString()
.equals(" ") == false
|| price_widget.getText().toString().equals(" ") == false) {
double editTextCalc = Double.parseDouble(amount_widget
.getText().toString())
/ Double.parseDouble(price_widget.getText()
.toString());
editTextCalc = Math.round(editTextCalc * 100) / 100.0;
literPrice_widget.setText(String.valueOf(decimalFormat
.format(editTextCalc)));
}
} catch (Exception e) {
// TODO: handle exception
}
break;
}
}
}
OK i just started to review my code again. Why hasn't anyone found an answer? It's really not that hard.
So i just just surrounded the if-statements in every try block with another if-statement which looks like this:
if(edittext.isFocused()){
try-catch block
}
And now everything works just fine. There is no StackOverflowException anymore because the textwatcher only starts it's work where the edittext is focused. The text changes do not trigger an infinit loop anymore.
You should check if change in an EditText happened because of changes made in other EditText. Create a boolean field in the class and initialize it with false:
private boolean mIsChanging = false;
In afterTextChanged() check if this field is false or exit otherwise:
public void afterTextChanged(Editable editable) {
if (mIsChanging) {
return;
}
mIsChanging = true;
// Then do what you did previously...
mIsChanging = false;
}
With Editable is possible, you need to use hashCodeFunction
#Override
public void afterTextChanged(Editable s) {
if (editText.getText().hashCode() == s.hashCode()) {
// some
}
}