Reputation: 18298
I have a EditText
field, variable name valueInputField
.
I listen to the text input change, what I want to achieve is during inputting, when the input format DOESN'T matches a regular expression, I would like to stop showing more inputs, but keep the field focused & user is able to type on keyboard still just that no real effect will take to the field.
@OnTextChanged(R.id.value_input)
protected void onTextChanged(CharSequence charSequence) {
String inputChars = charSequence.toString().trim();
// if doesn't match regular expression, stop showing more inputs
if (!inputChars.matches(MY_REGEXP)) {
// this doesn't achieve what I need.
valueInputField.setInputType(0)
}
}
I tried above way, it doesn't work. How to achieve what I need?
Upvotes: 13
Views: 937
Reputation: 306
Disabling the input type for edit text does not work properly when its focussed or being edited. Once you set the inout type to null, the view will start to receive the keypress callback methods. So, have class variable to validate the field and cancel the keys pressed. Here sample code goes.
public class SplashActivity extends AppCompatActivity{
EditText valueInputField;
private boolean allowValueField2Edit = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
....
valueInputField.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2{
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
String inputChars = charSequence.toString().trim();
// if doesn't match regular expression, stop showing more inputs
if (!inputChars.matches(MY_REGEXP)) {
// this doesn't achieve what I need.
valueInputField.setInputType(InputType.null);
allowValueField2Edit = false;
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
//Once you set the input type to none fore edit control, on Key lister will receive callbacks
valueInputField.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
//Here, you can add your custom logic to have key actions.
//retrun false will have key effect, return true
return !allowValueField2Edit;
}
});
Hope this helps...
Upvotes: 1
Reputation: 1777
If you want to stop suggestions in edit text you should try something like:
editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
And to enable again after any condition use this:
editText.setInputType(InputType. TYPE_CLASS_TEXT);
Here is an example with input with a threshold of size, here should work with your regex too:
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(s.length()< threshold){
editText.setInputType(InputType. TYPE_CLASS_TEXT);
}
if(s.length()>= threshold){
editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
Upvotes: 1
Reputation: 7086
Pseudocode:
Source code:
editText.addTextChangedListener(new TextWatcher() {
...
@Override
public void afterTextChanged(Editable editable) {
String text = editable.toString();
// STEP 1
if(text.matches(myRegex) && !flag) {
// make sure that this code block is executed only once
flag = true;
// STEP 2
// when match is found, always return the same string
// therefore disabling further editing of the editText field
editText.setFilters(new InputFilter[]{
new InputFilter() {
@Override
public CharSequence filter(CharSequence charSequence, int i, int i1,
Spanned spanned, int i2, int i3) {
// STEP 3
return spanned.subSequence(i2, i3);
}
}
});
}
}
});
When setting input filter, please take note of the proper way to do it. Please check this SO answer by Steven Byle.
Upvotes: 0
Reputation: 10235
You are already doing setInputType(InputType.TYPE_NULL)
. But it should be used with withsetEnabled(false)
to get it worked.
This will change the background color too. It is highly recommended because it gives the user a clue that it won't accept input. However you can change it as setBackgroundColor(Color.TRANSPARENT)
if you wish.
If you want to hide the cursor, add setCursorVisible(false)
.
Alternatively you can use afterTextChanged
instead of onTextChanged
so that you will be able to manipulate the text.
Upvotes: 2
Reputation: 958
maybe you should try below logic
maxLength=inputChars.length
if (!inputChars.matches(MY_REGEXP)) {
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
}
above program will set a max length of EditText when it does not match regexp.
Upvotes: 3
Reputation: 2407
You have to add an InputFilter to your textView:
here's an example:
editText.filters = arrayOf(object: InputFilter {
override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence {
if (Regex("[0-9]*").matches(source!!)) {
return source
} else {
return source.subSequence(start, end-1)
}
}
})
This filter method gets called everytime the input in the editText is being invoked. You can return the source when it matches a regex, otherwise, you can return a subSequence of the source, without the last char inserted.
The code example is in Kotlin, the translation shouldn't give you any problem :)
Upvotes: 2