How can I customize input type of editext shown in the given figure.Basically my requirement is that edittext should show only the last 3 or 4 digits only initial 12 digit should be in password mode.
You need to add a TextWatcher onto the EditText:
int characterCount = 0;
int asteriskCount = 0;
CharSequence input = null;
input.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
characterCount = count;
//update input sequence based on changes.
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//update input sequence based on changes.
}
#Override
public void afterTextChanged(Editable s) {
if (asteriskCount != characterCount) {
//make the visible sequence here.
CharSequence seq = "";
for (int i = 0; i < (characterCount <= 12 ? characterCount : 12); i++) {
seq = seq + "*";
}
if (characterCount > 12) {
for (int i = 12; i < characterCount; i++) {
seq = seq + characterCount.charAt(i);
}
}
asteriskCount = characterCount;
input.setText(seq);
}
}
});
There is no built in feature like this. So you have to do it by yourself. You have to make change on the text when the text is changed. To do so .
If you create a custom editText by extending EditText then you can overwrite the onTextChanged method and hanlde the changes.
Or you can use a TextWatcher to hadle changes.
So when the text is changed set the data except last 3 digitst to *.
But remember that you have to use a String field to store original data in a field.
Below is the code snippet of my TextWatcher:
private boolean spaceDeleted;
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
characterCount = start;
//update input sequence based on changes.
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// check if a space was deleted
CharSequence charDeleted = s.subSequence(start, start + count);
spaceDeleted = " ".equals(charDeleted.toString());
}
#Override
public void afterTextChanged(Editable s) {
if(s.length()>12){
return;
}
System.out.println("Character Count in afterTextChange->"+characterCount);
System.out.println("Editable Character->"+s);
ccNumber.removeTextChangedListener(this);
// record cursor position as setting the text in the textview
// places the cursor at the end
int cursorPosition = ccNumber.getSelectionStart();
String withSpaces = formatText(s);
ccNumber.setText(withSpaces);
// set the cursor at the last position + the spaces added since the
// space are always added before the cursor
ccNumber.setSelection(cursorPosition + (withSpaces.length() - s.length()));
// if a space was deleted also deleted just move the cursor
// before the space
if (spaceDeleted) {
ccNumber.setSelection(ccNumber.getSelectionStart() - 1);
spaceDeleted = false;
}
// enable text watcher
ccNumber.addTextChangedListener(this);
}
private String formatText(CharSequence s) {
// TODO Auto-generated method stub
StringBuilder formatted = new StringBuilder();
int count = 0;
/* if(s.length()<12){
formatted.append("*");
}else{
formatted.append(s.charAt(characterCount));
}*/
for (int i = 0; i < s.length(); ++i)
{
formatted.append("*");
/*if (Character.isDigit(s.charAt(i)))
{
if (count % 4 == 0 && count > 0)
formatted.append(" ");
formatted.append(s.charAt(i));
++count;
}*/
}
return formatted.toString();
}
});
Related
In android edit text, how to separate 10 digit number input by space? I am using android text watcher and I am trying to input multiple 10 digit numbers in the field. The issue arises when multiple numbers are copied and pasted in the field and that time, it doesn't take those spaces. Kindly let me know a solution in order to allow multiple number input with a space after every 10 digit number, when the number is copied from other place.
This will work for both type and copy/paste from other place.
yourEditText.addTextChangedListener(new TextWatcher() {
private static final char space = ' ';
#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) {
int pos = 0;
while (true) {
if (pos >= s.length()) break;
if (space == s.charAt(pos) && (((pos + 1) % 11) != 0 || pos + 1 == s.length())) {
s.delete(pos, pos + 1);
} else {
pos++;
}
}
pos = 10;
while (true) {
if (pos >= s.length()) break;
final char c = s.charAt(pos);
if (Character.isDigit(c)) {
s.insert(pos, "" + space);
}
pos += 11;
}
}
});
Edit and Use the following code as per your needs
StringBuilder s;
s = new StringBuilder(yourTxtView.getText().toString());
for(int i = 10; i < s.length(); i += 10){
s.insert(i, " "); // this line inserts a space
}
yourTxtView.setText(s.toString());
and when you need to get the String without spaces do this:
String str = yourTxtView.getText().toString().replace(" ", "");
I was implemented like after 4 digits hyphen display automatically like(2015-07) in edittext. my code works fine, but problem is while i delete before 4 digits value and again type it not working. addTextChangedListener not trigger when i edidtext retype like 2015-07 to 2014-07. But while i using "/" instead of "-" i can retype value. What is the problem?
mEdtProductionCode.addTextChangedListener(new TextWatcher() {
int prevL = 0;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
prevL = mEdtProductionCode.getText().toString().length();
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
int length = s.length();
if ((prevL < length) && length == 4) {
String data = mEdtProductionCode.getText().toString();
mEdtProductionCode.setText(data + "-");
mEdtProductionCode.setSelection(length + 1);
}
}
});
You should just move your character checking to the character after the fifth character has been entered, and then chop down String to put the custom character in between:
#Override
public void afterTextChanged(Editable s) {
int length = s.length();
if ((prevL <= length) && length == 5) {
String data = mEditProductionCode.getText().toString();
String beginData = data.substring(0,4);
String endData = Character.toString(data.charAt(length-1));
mEditProductionCode.setText(beginData + "-" + endData);
mEditProductionCode.setSelection(length + 1);
}
}
You can also use data.charAt(length-1) != '-' to check if user manually made dash input, in which case you just ignore and do not make changes to TextEdit.
eText.addTextChangedListener(new TextWatcher(){
public void afterTextChanged(Editable s) {
int wordvalue = 0;
int numvalue = 0;
for(int i=0; i<s.length(); i++) {
wordvalue += this.calcCharValue(s.charAt(i));
numvalue = this.calcCharValue(s.charAt(i));
String userEntered = nText.getText().toString();
userEntered = userEntered + numvalue;
tv.setText(String.valueOf(wordvalue));
nText.setText(String.valueOf(userEntered));
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){}
protected int calcCharValue(char a) {
Character ch = new Character(a);
if(ch >= 'A' && ch <= 'Z') { // a=1, b=2, c=3, ..., z=26
Character ca = new Character('A');
return ch.charValue() - ca.charValue() + 1;
}
I am try to create an app that get the text value from the word.
for example
a = 1, b = 2,
I am able to add them like abc = 6, abcd = 10
Now what my problem is I try this value as
abc = 123 and abcde = 12345
but what I get is
abc = 112123 and abcde = 1 12 123 1234 12345
It repeat the every character before and then add next value so how can I handle this repeated problem.
i need to remove characters if i add any special symbols to the edit text while am entering data to it.for example i am type a word smwinæ æ is a special characters so if i add that chareter edit text should remove the æ and display only smwin by replacing æ .i used text change listener. check the code below
email.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
// Abstract Method of TextWatcher Interface.
System.out.println("started after");
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
System.out.println("started");
// Abstract Method of TextWatcher Interface.
}
public void onTextChanged(CharSequence searchcontact, int start,
int before, int count) {
System.out.println("sssssssssss"+searchcontact);
String a=searchcontact.toString();
System.out.println("casted "+a);
String[] parts = a.split(" ");
String lastWord = parts[parts.length - 1];
System.out.println("------------------------------"+lastWord);
// String lastWord = a.substring(a.lastIndexOf(" ")+1);
// System.out.println("lastword"+lastWord);
if(a.equals("p"))
{
try {
email.getText().delete(email.getSelectionEnd() - 1, email.getSelectionStart());
} catch (Exception e) {
try {
email.getText().delete(email.length() - 1, email.length());
} catch (Exception myException) {
//textfield.getText().delete(textfield.length(), textfield.length() - 1);
}
}
// Method User For Sort Out THE Words
// in
// The SearchBar
}
}
});
here when text change i try to get the last word in the string but i failed to do this.used
String a=searchcontact.toString();
System.out.println("casted "+a);
String[] parts = a.split(" ");
String lastWord = parts[parts.length - 1];
to get the last word but it prints the entire string in the edittext how can i do this please help
You can add a TextWatcher to an EditText and get notified each time the text is notified. Using that, you can just parse the String to find the characters after a space, and update them to uppercase.
Here's a quick test I made which works pretty well (far from optimal, because each time you edit the Editable it calls the listener again...).
editText.addTextChangedListener(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) {
String string = s.toString();
int index = -1;
while (((index = string.indexOf(' ', index + 1)) != -1) && (index + 1 < string.length())) {
// Get character
char c = string.charAt(index + 1);
if (Character.isLowerCase(c)) {
// Replace in editable by uppercase version
s.replace(index+1, index + 2, Character.toString(c).toUpperCase());
}
}
}
});
To avoid being called to often, you could make all the changes in a char[] and only commit to the Editable if changes were made.
A simpler solution is probably to just use split(' ') on your String, replace all first letters in the String[] by the uppercase version (if needed), and commit only once to the Editable.
A simpler optimisation would be to add a boolean to your anonymous class, set it to try when you enter afterTextChanged, set it back to false when you exit it, and only process the string if the boolean is false.
I am using InputFilter class to make a masked EditText supporting digit grouping. For example when the user inserts" 12345" I want to show "12,345" in EditText. How can I implement it?
This is my incomplete code:
InputFilter IF = new InputFilter() {
#Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (!Character.isLetterOrDigit(source.charAt(i))) {
return "";
}
}
if (dest.length() > 0 && dest.length() % 3 == 0)
{
return "," + source;
}
return null;
}
};
edtRadius.setFilters(new InputFilter[] { IF });
Is there any other way to implement this kind of input mask?
This an improvement on the response from #vincent. It adds checks on deleting spaces in a number in the format 1234 5678 9190 so when trying to delete a space it just moves the cursor backon character to the digit before the space. It also keeps the cursor in the same relative place even if spaces are inserted.
mTxtCardNumber.addTextChangedListener(new TextWatcher() {
private boolean spaceDeleted;
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// check if a space was deleted
CharSequence charDeleted = s.subSequence(start, start + count);
spaceDeleted = " ".equals(charDeleted.toString());
}
public void afterTextChanged(Editable editable) {
// disable text watcher
mTxtCardNumber.removeTextChangedListener(this);
// record cursor position as setting the text in the textview
// places the cursor at the end
int cursorPosition = mTxtCardNumber.getSelectionStart();
String withSpaces = formatText(editable);
mTxtCardNumber.setText(withSpaces);
// set the cursor at the last position + the spaces added since the
// space are always added before the cursor
mTxtCardNumber.setSelection(cursorPosition + (withSpaces.length() - editable.length()));
// if a space was deleted also deleted just move the cursor
// before the space
if (spaceDeleted) {
mTxtCardNumber.setSelection(mTxtCardNumber.getSelectionStart() - 1);
spaceDeleted = false;
}
// enable text watcher
mTxtCardNumber.addTextChangedListener(this);
}
private String formatText(CharSequence text)
{
StringBuilder formatted = new StringBuilder();
int count = 0;
for (int i = 0; i < text.length(); ++i)
{
if (Character.isDigit(text.charAt(i)))
{
if (count % 4 == 0 && count > 0)
formatted.append(" ");
formatted.append(text.charAt(i));
++count;
}
}
return formatted.toString();
}
});
In case you're still searching, I ran into this problem the last day, and found that using a TextWatcher is the best (still not really good) option. I had to group digits of credit card numbers.
someEditText.addTextChagedListener(new TextWatcher()
{
//According to the developer guide, one shall only edit the EditText's
//content in this function.
#Override
public void afterTextChanged(Editable text)
{
//You somehow need to access the EditText to remove this listener
//for the time of the changes made here. This is one way, but you
//can create a proper TextWatcher class and pass the EditText to
//its constructor, or have the EditText as a member of the class
//this code is running in (in the last case, you simply have to
//delete this line).
EditText someEditText = (EditText) findViewById(R.id.someEditText);
//Remove listener to prevent further call due to the changes we're
//about to make (TextWatcher is recursive, this function will be
//called again for every change you make, and in my experience,
//replace generates multiple ones, so a flag is not enough.
someEditText.removeTextChangedListener(this);
//Replace text with processed the processed string.
//FormatText is a function that takes a CharSequence (yes, you can
//pass the Editable directly), processes it the way you want, then
//returns the result as a String.
text.replace(0, text.length(), FormatText(text));
//Place the listener back
someEditText.addTextChangedListener(this);
}
#Override
public void beforeTextChaged(CharSequence s, int start, int count, int after)
{
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
});
My formatting function for the credit card numbers looked like this:
String FormatText(CharSequence text)
{
StringBuilder formatted = new StringBuilder();
int count = 0;
for (int i = 0; i < text.length(); ++i)
{
if (Character.isDigit(text.charAt(i)))
{
//You have to be careful here, only add extra characters before a
//user-typed character, otherwise the user won't be able to delete
//with backspace, since you put the extra character back immediately.
//However, this way, my solution would put a space at the start of
//the string that I don't want, hence the > check.
if (count % 4 == 0 && count > 0)
formatted.append(' ');
formatted.append(text.charAt(i));
++count;
}
}
return formatted.toString();
}
You might have to mind other issues as well, since this solution actually rewrites the EditText's content every time a change is made. For example, you should avoid processing characters you inserted yourself (that is an additional reason for the isDigit check).
use simple function:
public String digit_grouping(String in_digit){
String res = "";
final int input_len = in_digit.length();
for(int i=0 ; i< input_len ; i++)
{
if( (i % 3 == 0) && i > 0 )
res = "," + res;
res = in_digit.charAt(input_len - i - 1) + res;
}
return res;
}