I am working to validate the name field, since there are so many country using different symbol as first, last name, I am going to validate the field by checking whether there is a number among the characters
private static final String NAME_REGEX = "\\d*";
public static boolean isName(EditText editText) {
return isValid(editText, NAME_REGEX) ? false : true; //Match digit pattern return true , meaning it is not a valid name
}
public static boolean isValid(EditText editText, String regex) {
String text = editText.getText().toString().trim();
return Pattern.matches(regex, text) ? true : false;
}
However, this pattern seems not working as I add some number it is still valid , what is the correct way of implement this? Thanks a lot
Just do this
private static final String NAME_REGEX = ".*\\d.";
I think this will work.
Do not use regx. InputFilter is proper way to do this kind of validation.
public class MainActivity extends Activity {
EditText edit;
InputFilter filter = new InputFilter() {
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (source.length() > 0) {
if (Character.isDigit(source.charAt(0)))
return "";
}
return null;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = (EditText) findViewById(R.id.edit);
edit.setFilters(new InputFilter[] { filter });
}
}
If you set the EditText to inputType to "textPersonName" there is no need for validation.
android:inputType="textPersonName"
Related
So if a user enters "1234" they will see "1234" in the EditText field. but when that field loses focus I want it to show "****"
So I've implemented a custom TransformationMethod that will only mask the entered text if the EditText field does not have focus.
when I enter the text "12345" it shows it as it should "12345" but when I click on a different field the numbers never get masked. I want to see "*****" but I still see the same "12345"
If I rotate the device though (force it to reload everything) it correctly shows "*****". And when I click on the EditText Field it correctly changes the masked text from "*****" to "12345" So it works when gaining focus but not when losing focus. I've tried implementing an OnFocusChangeListener but it seems to have no affect.
Is there any way I can force the EditText Field to redraw the text when it loses focus?
SetUp:
editText.setTransformationMethod(CustomPasswordTransformationMethod(numUnobfuscatedDigits))
editText.setOnFocusChangeListener { view, hasFocus ->
((EditText)view).invalidate()
((EditText)view).refreshDrawableState()
CustomPasswordTransformationMethod:
public class CustomPasswordTransformationMethod extends PasswordTransformationMethod {
private int unObfuscated = 1;
private boolean mIsFocused = false;
/**
* #param number the number of digits that will be unObfuscated at the end of the input string. Must be a positive integer or 0.
*/
public CustomPasswordTransformationMethod(int number) {
if (number < 0) {
Log.e(TAG, "Invalid parameter number =" + number + " number of un-obfuscated digits must be a positive integer or 0.");
unObfuscated = 0;
}
unObfuscated = number;
}
#Override
public CharSequence getTransformation(CharSequence source, View view) {
return new PasswordCharSequence(source);
}
#Override
public void onFocusChanged(View view, CharSequence sourceText,
boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(view,sourceText,focused, direction, previouslyFocusedRect);
mIsFocused = focused;
}
private class PasswordCharSequence implements CharSequence {
private CharSequence mSource;
public PasswordCharSequence(CharSequence source) {
mSource = source; // Store char sequence
}
public char charAt(int index) {
if(mIsFocused) return mSource.charAt(index);
else {
if (index < ((length()) - unObfuscated)) return '●';
return mSource.charAt(index);
}
}
public int length() {
return mSource.length(); // Return default
}
public CharSequence subSequence(int start, int end) {
return mSource.subSequence(start, end); // Return default
}
}
};
Try this and see if it does what you need.
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean hasFocus) {
if(hasFocus){
editText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
}
else{
editText.setTransformationMethod(PasswordTransformationMethod.getInstance());
}
}
});
Maybe you can try to keep it simple:
String password = "";
editText.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus) {
editText.setText(password, TextView.BufferType.EDITABLE);
} else {
password = editText.getText().toString();
String ofuscated = "";
for (int i = 0; i < password.length(); i++){ ofuscated += "*"; }
editText.setText(ofuscated, TextView.BufferType.EDITABLE);
}
}
});
I like to convert on the fly letters from cyrillic to latin. For example when user enter cyrillic letter I like to convert letter to latin. Here is the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
test = (EditText) findViewById(R.id.test);
InputFilter filter = new InputFilter() {
TransliterationHelper tr = new TransliterationHelper();
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
if (tr.isAlphaCyrilic(source.toString())) {
String convertedString = tr.returnLatinForCyrilic(source.toString());
return convertedString.toUpperCase();
} else if (tr.isAlpha(source.toString()))
return source.toString().toUpperCase();
else
return "";
return null;
}
};
test.setFilters(new InputFilter[]{filter});
}
Here is isAlphaCyrilic function:
public static boolean isAlphaCyrilic(String s) {
boolean isCyrilic = false;
for (char c : s.toCharArray()) {
if (Character.UnicodeBlock.of(c) == Character.UnicodeBlock.CYRILLIC) {
isCyrilic = true;
break;
}
}
return isCyrilic;
}
Here is the code for isAlpha
public static boolean isAlpha(String s) {
String pattern = "^[a-zA-Z ]*$";
if (s.matches(pattern)) {
return true;
}
return false;
}
The function returnLatinForCyrilic, return matched character for cyrillic letter:
public String returnLatinForCyrilic(String s) {
String strTranslated = cyrilicToLatinMap.get(s);
return strTranslated;
}
For example I enter only latin letters or cyrillic letters everything works ok, but when I enter cyrillic letter after latin (I changed keyboard language) method filter called again, and I don't like that.
Does someone has some idea?
I put android:inputType="textNoSuggestions"
so the method filter was not called twice.
I am having a problem with setError() on EditText. When an activity is opened, it checks if certain fields are empty and sets error message on them if true. However, the exclamation mark icon is only displayed in case I write some text in field and then delete it. If I lose focus on that field, the icon will disappear again. Both fields Naam and Telefonnumer have this validation.
I use Android 2.2.2 SDK and the application is run on Nexus 7 with latest updates.
I have Util class:
public class Util {
private static String TAG = "Util Class";
public static boolean editTextIsEmpty(EditText edittext) {
if (edittext.getText().toString().trim().length() < 1)
return true;
else
return false;
}
public void editTextListener(final EditText editText) {
editText.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (editTextIsEmpty(editText) && editText.isEnabled())
editText.setError("Nodig");
else
editText.setError(null);
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (editTextIsEmpty(editText) && editText.isEnabled())
editText.setError("Nodig");
else
editText.setError(null);
}
});
}
}
and then I have method validateInput() in my activity:
public class DeliveryActivity extends BaseActivity {
private ImageButton btnSetDate;
private Button btnToSummary;
private Button btnSearchAddress;
private EditText txtPostcode;
private EditText txtHouseNumber;
private EditText txtHouseNumberSuffix;
private EditText txtStreet;
private EditText txtCity;
private EditText txtDeliveryDate;
private EditText txtName;
private EditText txtPhone;
private EditText txtEmail;
private EditText txtRemark;
private TextView lblExtraDeliveryInfo;
private Spinner spinnerDelivery;
private Spinner spinnerDeliveryPeriod;
private Spinner spinnerContact;
private Spinner spinnerDeliveryAddress;
private Spinner spinnerExtraDeliveryInfo;
private RelativeLayout rlDeliveryAddressDetails;
private DevRestHelper additionalDeliveryInfo;
private DevRestHelper searchClientAddress;
private Util util = new Util();
private int year;
private int month;
private int day;
public static final int DIALOG_DATEPICKER = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_delivery);
initControls();
validateInput();
}
private void initControls() {
btnSetDate = (ImageButton) findViewById(R.id.activity_delivery_btnCalendar);
btnToSummary = (Button) findViewById(R.id.activity_delivery_btnSummary);
btnSearchAddress = (Button) findViewById(R.id.activity_delivery_btnSearchAddress);
spinnerDelivery = (Spinner) findViewById(R.id.activity_delivery_spinnerDeliveryMethod);
spinnerDeliveryPeriod = (Spinner) findViewById(R.id.activity_delivery_spinnerDeliveryPeriod);
spinnerContact = (Spinner) findViewById(R.id.activity_delivery_spinnerContactperson);
spinnerDeliveryAddress = (Spinner) findViewById(R.id.activity_delivery_spinnerDeliveryAddress);
spinnerExtraDeliveryInfo = (Spinner) findViewById(R.id.activity_delivery_spinnerExtraDeliveryInformation);
txtPostcode = (EditText) findViewById(R.id.activity_delivery_txtPostcode);
txtHouseNumber = (EditText) findViewById(R.id.activity_delivery_txtHousenumber);
txtHouseNumberSuffix = (EditText) findViewById(R.id.activity_delivery_txtHousenumberSuffix);
txtStreet = (EditText) findViewById(R.id.activity_delivery_txtStreet);
txtCity = (EditText) findViewById(R.id.activity_delivery_txtCity);
txtDeliveryDate = (EditText) findViewById(R.id.activity_delivery_txtDeliveryDate);
txtName = (EditText) findViewById(R.id.activity_delivery_txtName);
txtPhone = (EditText) findViewById(R.id.activity_delivery_txtPhone);
txtEmail = (EditText) findViewById(R.id.activity_delivery_txtEmail);
txtRemark = (EditText) findViewById(R.id.activity_delivery_txtRemark);
lblExtraDeliveryInfo = (TextView) findViewById(R.id.activity_delivery_lblExtraDetailInformation);
rlDeliveryAddressDetails = (RelativeLayout) findViewById(R.id.activity_delivery_rlDeliveryAddressDetails);
}
private void validateInput() {
util.editTextListener(txtPostcode);
util.editTextListener(txtHouseNumber);
util.editTextListener(txtDeliveryDate);
}
}
Let me just say that code work on BlueStacks emulator.
There is a known bug with setError on Jelly Bean_MR1 (4.2 and 4.2.1). I am however assuming that the Nexus 7 you are testing with is running one of those versions of Android. See here: http://code.google.com/p/android/issues/detail?id=40417
The error will be shown while you have focus on that EditText field, but when you lose focus, the error icon is not visible to notify the user of the problem.
Before you set Error on any view or edit text, just call the
yourEditText.requestFocus();
yourEditText.setError("Your Error Message");
then set Error. it will solve your problem. Atleast mine did.
try this
new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
if (editTextIsEmpty(editText) && editText.isEnabled())
editText.setError("Nodig");
else
editText.setError(null);
}
#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
}
}
You can use following code:
May it will be helpful to you:
mPopupInlineErrorBackgroundId = getResourceId(mPopupInlineErrorBackgroundId,
com.android.internal.R.styleable.Theme_errorMessageBackground);
mView.setBackgroundResource(mPopupInlineErrorBackgroundId);
However, you can set a Spanned and a custom error icon using the overloaded setError(CharSequence, Drawable).
You can easily create a Spanned from HTML using fromHtml().
For Example:
yourEditText.setError(Html.fromHtml("<font color='blue'>this is the error</font>"));
This is the only you need to get expected setError behaviour on the TextView
android:focusable="true"
android:clickable="true"
android:focusableInTouchMode="true"
I want to apply InputFilter to my EditTextPreferences...
Before I used the PreferenceActivity I had EditTexts with Filters like that:
et1 = (EditText) findViewById(R.id.editText1);
et2 = (EditText) findViewById(R.id.ETminsim);
et3 = (EditText) findViewById(R.id.ETdelay);
et1.setText(Integer.toString(PlotView.playlist_size), EditText.BufferType.EDITABLE);
et2.setText(Integer.toString(conversorToInt(PlotView.min_sim)), EditText.BufferType.EDITABLE);
et3.setText(Integer.toString(MusicService.getSeek()/1000), EditText.BufferType.EDITABLE);
et1.setFilters(new InputFilter[]{ new InputFilterMinMax(1, 30)});
et2.setFilters(new InputFilter[]{ new InputFilterMinMax(0, 100)});
et3.setFilters(new InputFilter[]{ new InputFilterMinMax(0, 300)});
But how can I reference to the EditTexts of the EditTextPreference in order to set these Filters?
My new Code:
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
getPreferenceManager().setSharedPreferencesName(Singleton.PREFS_NAME);
addPreferencesFromResource(R.xml.prefs);
//TODO set InputFilter
}
Konstantin had it mostly correct. Combine his answer with Sebastian's comment on his answer and you get
EditText editText1 = ((EditTextPreference) findPreference(preference_1_key))
.getEditText();
editText1.setFilters(new InputFilter[]{ new InputFilterMinMax(1, 30) });
Assuming this is your preference Activity and you can get the items by id:
EditTextPreference editTextPreference = findByViewId(R.id.editPref1);
EditText editText = editTextPreference.getEditText();
editText.setFilters(................);
This has more flexibility.
public class Utility {
public static void setEditTextInputFilter(EditText editText, final String blockCharacterSet) {
InputFilter filter = new InputFilter() {
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (source != null && blockCharacterSet.contains(("" + source))) {
return "";
}
return null;
}
};
editText.setFilters(new InputFilter[]{filter});
}
}
How to use:
exampleEditText is the editText which want to block input "-".
Utility.setEditTextInputFilter(exampleEditText, "-");
I have EditText field with android:numeric="decimal" and android:inputType="phone" for entering decimal numbers. I use input type phone because it is more easy to user enter numbers.
For any device with soft keyboard I haven't any problem but when I begin use hard keyboard when will print wrong numbers (for example when I use HTC Desire Z).
How to solve this problem?
P.S. I developed the "Simple Loan Calculator" for Android - it's opensource and freeware
Solved!
AndroidManifest.xml
<activity android:name=".MainActivity" android:label="#string/app_name" android:configChanges="keyboardHidden|orientation|keyboard" >
MainActivity.java
public void onCreate(Bundle savedInstanceState) {
....
setPriceInputFilter(amountEdit, interestEdit, fixedPaymentEdit, periodYearEdit, periodMonthEdit, downPaymentEdit, disposableCommissionEdit, monthlyCommissionEdit);
....
}
private void setPriceInputFilter(EditText ... fields){
PriceInputFilter filter = new PriceInputFilter();
for (EditText field: fields){
field.setFilters(new InputFilter[]{filter});
}
}
public void onConfigurationChanged(Configuration newConfig) {
if(newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO){
setInputType(InputType.TYPE_NULL, amountEdit, interestEdit, fixedPaymentEdit, periodYearEdit,
periodMonthEdit, downPaymentEdit, disposableCommissionEdit, monthlyCommissionEdit);
Toast.makeText(this, "HARD-keyboard", Toast.LENGTH_SHORT).show();
}else{
setInputType(InputType.TYPE_CLASS_PHONE, amountEdit, interestEdit, fixedPaymentEdit, periodYearEdit,
periodMonthEdit, downPaymentEdit, disposableCommissionEdit, monthlyCommissionEdit);
Toast.makeText(this, "SOFT-keyboard", Toast.LENGTH_SHORT).show();
}
super.onConfigurationChanged(newConfig);
}
private void setInputType(int type , EditText ... fields){
for (EditText field: fields){
field.setInputType(type);
}
}
PriceInputFilter.java
public class PriceInputFilter implements InputFilter {
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String checkedText = dest.toString() + source.toString();
String pattern = getPattern();
if (!Pattern.matches(pattern, checkedText)) {
return "";
}
return null;
}
private String getPattern() {
return "[0-9]+([.]{1}||[.]{1}[0-9]{1,2})?";
}
}