Intercept Number 0 to 9 in Android EditText - android

I want to intercept 0 to 9 button key events from soft keyboard in android. I have tried many ways but didn't succeed. any little help will help me a lot.
what I am doing is,
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode==KeyEvent.KEYCODE_12)
{
Toast.makeText(context, "Pressed", Toast.LENGTH_LONG).show();
return true;
}
return super.onKeyDown(keyCode, event);
}
in my custom EditText class but it is not working what am i missing? i have tried many key codes but no result in hand.

Use a text watcher, its much simpler:
At Class level:
EditText editText;
in onCreate:
editText = (EditText)findViewById(R.id.yourEdittext)
editText.addTextChangedListener(mTextEditorWatcher);
Outside onCreate(Class level) :
final TextWatcher mTextEditorWatcher = new TextWatcher(){
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("Entered text: "+editText.getText());
// USe edit_text.getText(); here
}
public void afterTextChanged(Editable s) {
}
};
If you want to restrict the entry on your Edit Text to only alphabets add this in the XML of your edit text control:
android:digits="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
If you dont like the above and want to achieve this through code, use the following:
editText.setFilters(new InputFilter[] {
new InputFilter() {
public CharSequence filter(CharSequence chr, int start,
int end, Spanned dst, int dstart, int dend) {
if(chr.equals("")){
return chr;
}
if(chr.toString().matches("[a-zA-Z ]+")){
return chr;
}
return "";
}
}
});

Related

Android EditText data entry in lowercase determined at runtime

I was rather surprised that this was not a native function of EditText, but I can't find any mechanism that will convert inputs to lower case as they are entered into an EditText field. The EditText field determines whether to be lowercase at runtime, so I can't have this in the XML, it needs to be fired as I allocate the EditText. I have tried:
1) Negating the ALL Caps:
mEntry.setInputType(InputType.TYPE_CLASS_TEXT | ~InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
2) Creating a listener:
private TextWatcher textWatcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!Utilities.stringIsBlank(mField.getFormat()) && Field.LOWER.equalsIgnoreCase(mField.getFormat())) {
if (!Utilities.stringIsBlank(s.toString()) && !s.toString().equals(s.toString().toLowerCase()) ) {
mEntry.setText(s.toString().toLowerCase());
mEntry.setSelection(start+1);
}
}
}
}
The problem with this is that when I call the setText() it recursively calls back to the onTextChange event, which messes with the location of cursor, depending on what it is changing.
Anyone have a simple solution that I have somehow missed?
You can use a filter. Below is a modified AllCaps filter to convert everything to lowercase in stead of uppercase.
/**
* This filter will lower case all the capitalized letters that are added
* through edits.
*/
public static class NoCapsFilter implements InputFilter {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (Character.isUpperCase(source.charAt(i))) {
char[] v = new char[end - start];
TextUtils.getChars(source, start, end, v, 0);
String s = new String(v).toLowerCase();
if (source instanceof Spanned) {
SpannableString sp = new SpannableString(s);
TextUtils.copySpansFrom((Spanned) source,
start, end, null, sp, 0);
return sp;
}
else {
return s;
}
}
}
return null; // keep original
}
}
Then just set the filter on your EditText.
mEntry.setFilters(new InputFilter[]{new NoCapsFilter()});
Check the text inside your if statement like this
if(mEntry.getText().toString().equals( mEntry.getText().toString().toLowerCase() )
return;
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!Utilities.stringIsBlank(mField.getFormat()) && Field.LOWER.equalsIgnoreCase(mField.getFormat())) {
if (!Utilities.stringIsBlank(s.toString()) && !s.toString().equals(s.toString().toLowerCase()) ) {
if (mEntry.getText().toString().equals(mEntry.getText().toString().toLowerCase())return;
mEntry.setText(s.toString().toLowerCase());
mEntry.setSelection(start+1);
}
}
}

How to change decimal seprator from "." to "," in EditText Android?

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:inputType="numberDecimal"
android:digits="0123456789,"
android:gravity="center"/>
After Defining digits it allow me to use "," but only problem I am facing that, I can enter "," multiple time. I want to restrict user so that he can input only one Decimal separator that is comma "," in my case.
I'm pretty sure it depends on the locale your device is on.
boolean hasComma = false;
InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
if (hasComma && (source.equals(".") || source.equals(",")))
{
return "";
}
return source;
}
};
// set input filter for edit text
editText.setFilters(new InputFilter[]{filter});
editText.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) {
if(!hasComma && s.toString().contains("."))
{
s= replaceComma(s.toString());
editText.setText(s);
editText.setSelection(start + 1);
hasComma =true;
}
}
#Override
public void afterTextChanged(Editable s) {
if (s.toString().contains(",") || s.toString().contains("."))
{
hasComma =true;
}
else {
hasComma = false;
}
}
});
//use this method to replace "." to ","
private CharSequence replaceComma(String s) {
return s.replace('.',',');
}

TextWatcher makes Typing slow in Edittext(Android)

The following code i am using for getting status of typing in Text Changes function.....
mEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
try {
session.typing();
} catch (OmegleException e) {
e.printStackTrace();
}
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
});
try something like this -guess is a chat app right so -
final Random ran = new Random();
mEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(start %2 ==0 && ran.nextBoolean()){
try {
session.typing();
} catch (OmegleException e) {
e.printStackTrace();
}
}
});
Edit
b4 i do your final request, do you mind runing session.typing on new Thread, like this
new Thread(new Runnable() {
#Override
public void run() {
try {
session.typing();
} catch (OmegleException e) {
e.printStackTrace();
}
}
}).start();
Edit 2
on first letter input
mEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(start ==1){
try {
session.typing();
} catch (OmegleException e) {
e.printStackTrace();
}
}
});
It can be fixed by changing the EditText width to 0dp using weighted widths to
match/fill the parent.
I don't know for sure why this was occurring, however I believe it is because when the width of the EditText is set to wrap content it will adjust/redraw itself so that everything fits. So by making the EditText have a fixed width, this redraw is no longer required.
What does the "0dp" signify for the width? That it should take up all the available space?
yes, it will. The layout_weight tag will do that.
<EditText
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"/>
For you problem i have one advice for you :
Set your status as typing till user don't press done button on keyboard.
editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
#Override
public boolean onEditorAction(EditText v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
//do here your stuff f
return true;
}
return false;
} });

EditText maximum characters limit exceeded callback

My idea is to set an error View to the EditText when the maximum character limit has been reached. Is there any callback about this event, or may be there's another way to achieve this effect? Thanks in advance.
maxLength attribute in the EditText is actually an InputFilter, which you can write yourself and supply from code.
You can look at the implementation of InputFilter.LengthFilter, which basically returns null if there is no overflow. (see http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/text/InputFilter.java#InputFilter.LengthFilter.filter%28java.lang.CharSequence%2Cint%2Cint%2Candroid.text.Spanned%2Cint%2Cint%29 )
you can create an extension to InputFilter.LengthFilter in which you call super and compare it to null to decide if you need to display an alert.
edit - with code
editText.setInputFilters(new InputFilter[] {
new InputFilter.LengthFilter(max) {
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
CharSequence res = super.filter(source, start, end, dest, dstart, dend);
if (res != null) { // Overflow
editText.setError("Overflow");
}
return res;
}
}
});
You can use the edit text's setError:
editText.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() > max)
editText.setError("Error");
}
});
I think the best solution is to use TextChangedListener and check the length of the EditText test versus your limit.
Thanks but-
editText.setFilters() not editText.setInputFilters()

How to delete instantly SPACE from an edittext if a user presses the space?

I have an edittext, and a textwatcher that watches if SPACE arrived or not. If its a SPACE I would like to delete that instantly. Or if its a space I want to make sure it doesnt appear but indicate somehow (seterror, toast) for the user that space is not allowed.
edittext.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
//---//
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
I cannot define onkeydown in the afterTextChaned method, since it gives me an error.
public boolean onKeyDown(int keyCode, KeyEvent event) {
super.onKeyDown(keyCode, event);
if (keyCode == KeyEvent.KEYCODE_SPACE) {
}
}
So it is not working (syntax error, misplaced construct for the int keyCode.
Thanks you in advance!
The solution is as usually much simpler:
#Override
public void afterTextChanged(Editable s) {
String result = s.toString().replaceAll(" ", "");
if (!s.toString().equals(result)) {
ed.setText(result);
ed.setSelection(result.length());
// alert the user
}
}
This shouldn't have the problems of the previous attempts.
setSelection is there to set the cursor again at the end of your EditText:
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2,
int arg3) {}
#Override
public void beforeTextChanged(CharSequence s, int arg1, int arg2,
int arg3) {}
#Override
public void afterTextChanged(Editable arg0) {
if(editText.getText().toString().contains(" ")){ editText.setText(editText.getText().toString().replaceAll(" " , ""));
editText.setSelection(editText.getText().length());
Toast.makeText(getApplicationContext(), "No Spaces Allowed", Toast.LENGTH_LONG).show();
}
}});
boolean editclicked =false ;
edittext.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
editclicked = false ;
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {
editclicked = true;
});
Put this as a separate function:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (editclicked) {
if (keyCode == KeyEvent.KEYCODE_SPACE) {
return false
}
} else {
super.onKeyDown(keyCode, event);
}
}
#Override
public void afterTextChanged(Editable s) {
String result = s.toString().replaceAll("\\s", "");
if (!s.toString().equals(result)) {
int pos = editText.getSelectionStart() - (s.length() - result.length());
editText.setText(result);
editText.setSelection(Math.max(0,Math.min(pos, result.length())));
editText.setError("No spaces allowed");
}
}
\s matches any whitespace character (equal to [\r\n\t\f\v ])
Setting selection like this, allow you to enter or paste text in middle of edittext without loosing cursor position
My relatively simple solution for instant whitespace deletion without removing spannables (styles) in EditText:
Remove at start:
#Override
public void afterTextChanged(Editable s) {
int i;
for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
s.replace(0, i, "");
}
Basically that's it, but you can also do:
Remove at start (without interrupting first input):
#Override
public void afterTextChanged(Editable s) {
String text = s.toString();
if(!text.trim().isEmpty()){
int i;
for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
s.replace(0, i, "");
}
}
Removing at start and end (allow 1 whitespace at end for convinient input):
#Override
public void afterTextChanged(Editable s) {
int i;
//remove at start
for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
s.replace(0, i, "");
//remove at end, but allow one whitespace character
for (i = s.length(); i > 1 && Character.isWhitespace(s.charAt(i-1)) && Character.isWhitespace(s.charAt(i-2)); i--) { ; }
s.replace(i, s.length(), "");
}
For removing the space instantly you can achieve it by two ways.
One simple solution you can set the digits to your edit text.
android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
second way you can set a filter
EditText.setFilters(new InputFilter[] { filter });
InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (Character.isSpaceChar(source.charAt(i))) {
return "";
}
}
return null;
}
}
One more simple way to achieve this using the input Filter
editText.setFilters(new InputFilter[]{new InputFilter() {
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (source.toString().equalsIgnoreCase(" ")){
return "";
}
return source;
}
}});
This will remove the space entered by the user immediately and gives appearance like space is disabled.

Categories

Resources