removeTextChangedListener on focus lost - java

I'm calling an onFocusChange method in a EditText, inside the method, when the field has the focus I call addTextChangedListener with a previously declared TextWatcher to the same field.
When the field lose focus I remove the TextWatcher.
But it look like not working, because in a second field I eventually need to set the text to the first field and it end with calling the TextWatcher that I previously removed.
et1.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
final TextWatcher watcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Do things
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Do things
}
#Override
public void afterTextChanged(Editable s) {
// Do things
}
};
if (hasFocus) {
et1.addTextChangedListener(watcher);
} else {
et1.removeTextChangedListener(watcher);
}
}
Then here start the code for the second field (using similar logic)
et2.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
final TextWatcher watcherEt2 = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Do things
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Do things
et1.setText("from things"); //here the removed TextWatcher is runned
}
#Override
public void afterTextChanged(Editable s) {
// Do things
}
};
if (hasFocus) {
et2.addTextChangedListener(watcherEt2);
} else {
et2.removeTextChangedListener(watcherEt2);
}
}
It's an Android Studio bug, or i miss something?

At first of all i'll recommend you not to create textWatcher in onFocusChange method because it doesn't matter constantly create it when onFocusChange will be called,
and then i want to ask why are you want to remove textWatchers, because if your EditText won't have focus it's the same, textWatcher will not work

Related

Request focus on edittext is not working correctly

I have 4 edittexts that act as a "enter your pin" field with each edittext set to only be able to take a single number before requesting focus to the next edittext. If I enter a number for the 1st pin, it then request focus to the 2nd, and then 3rd, etc.
What I am trying to do now is, if the user clicks on the 2nd edittext or 3rd and the 1st field has not been entered, it should go back and focus on the 1st field.
The edittext fields
I tried to do this using an onTouchListener and what I noticed is that after clicking on the 2nd edittext first instead of clicking on the left/1st edittext, I can see the focus going back to the first edittext but then immediately go back to the 2nd edittext almost a split second and ultimately still remain focus on the 2nd edittext.
I also tested using onClickListener. It does work but it takes two clicks. So I'll click on the 2nd edittext, nothing happens, and then I click it again which then moves the focus back to the 1st edittext but I need it to happen on the first click.
Here is part of the code
pin1EditTxt.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) {
if(pin1EditTxt.getText().toString().length()==1) //size as per your requirement
{
pin2EditTxt.requestFocus();
}
}
});
// pin2EditTxt.setOnTouchListener(new View.OnTouchListener() {
// #Override
// public boolean onTouch(View v, MotionEvent event) {
// if(pin1EditTxt.length() == 0){
// pin2EditTxt.clearFocus();
// pin1EditTxt.requestFocus();
// }
// return false;
// }
// });
pin2EditTxt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(pin1EditTxt.length() == 0){
pin1EditTxt.requestFocus();
}
}
});
pin2EditTxt.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) {
if(pin2EditTxt.getText().toString().length()==1) //size as per your requirement
{
pin3EditTxt.requestFocus();
}
}
});
pin3EditTxt.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) {
if(pin3EditTxt.getText().toString().length()==1) //size as per your requirement
{
pin4EditTxt.requestFocus();
}
}
});
pin4EditTxt.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) {
//Hide keyboard
InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
editTxtWrapper.requestFocus();
}
});
I guess you should be using pin1EditTxt.getText().toString().length()==0 instead of pin1EditTxt.length()==0 inside onclick.

Set Edit Text input between set min and max

I have an EditText that will put this sets of value
58.44,44.2 or even negative like -58.44,-44.2
how can I prevent it from surpassing between -100 and 100 i tried this link but no joy.
I wanna make my EditText to type between -100 and 100 only if surpasses then dont continue typing.
You can add the condition like this
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) {
}
#Override
public void afterTextChanged(Editable s) {
if (s.toString().length() > 0) {
String value = s.toString();
Double numericValue = Double.parseDouble(value);
if (numericValue < -100 || numericValue > 100) {
editText.setText("");
}
}
}
});
Set your EditText inputType as
android:inputType="numberDecimal|numberSigned"
If you want to solve programmatically, TextWatcher is a good option.
Inside onTextChanged(), Check if your changed CharSequence s, matches you need, otherwise replace it.
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) {
}
});
Using a regex pattern you can handle the numbers between -99.99 and 99.99
^[-+]?[0-9]{1,2}\.[0-9]{1,2}+$
Update 2:
For >=-100 and <=100, use this regex:
^[-+]100|^[-+]?[0-9]{1,2}.[0-9]{1,2}+$
Below sample, checks the text and enables/disables the button if matches or not.
EditText mEditText;
Button mButton;
final static String mRegex = "^[-+]100|^[-+]?[0-9]{1,2}\.[0-9]{1,2}+$";
boolean inputMatches;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText = findViewById(R.id.editText);
mEditText.addTextChangedListener(new InputController());
mButton = findViewById(R.id.button);
mButton.setEnabled(inputMatches);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(MainActivity.this," Input matches!", Toast.LENGTH_SHORT).show();
}
});
}
public class InputController implements 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) {
}
#Override
public void afterTextChanged(Editable editable) {
String input = mEditText.getText().toString();
inputMatches = input.matches(mRegex);
}
}
Update:
As per your request on clearing Edittext.. There are multiple ways to do it. You can either follow other answers above or you can use my above answer if it fits with you and instead using TextWatches, you can use OnFocusChangeListener. This is better if you have multiple Edittexts. When your one Edittext loses focus, then this code will trigger to see if it matches the regex pattern. If no match, clears it.
Remove above TextWatcher, follow bellow:
Implement OnFocusChangeListener in your Activity
MainActivity extends AppCompatActivity implements View.OnFocusChangeListener
Override its onFocusChange method.
#Override
public void onFocusChange(View view, boolean b) {}
Inside onFocusChange do your checks.
#Override
public void onFocusChange(View view, boolean b) {
if(!b){ // Lost focus
String text = ((EditText)view).getText().toString();
if(text.matches(mRegex)){
// It matches
Toast.makeText(MainActivity.this, "Input matches!!!", Toast.LENGTH_SHORT).show();
}
else{
// No match - clear Edittext
((EditText)view).setText("");
Toast.makeText(MainActivity.this, "Input doesn't match", Toast.LENGTH_SHORT).show();
}
}
}
Update 2
To include -100 and 100, use this regex pattern:
^[-+]100|^[-+]?[0-9]{1,2}.[0-9]{1,2}+$

Make EditText readonly on text change in another EditText

I want to create two editable EditText in android. When the user is entering data in one EditText, the other EditText automatically becomes read-only and shows the result of that entered data.
Try The Following Code
Consider two EditText e1 and e2
e1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
e2.setEnabled(false);
return false;
}
});
use this code. And apply your logic, first check if this EditText is empty the call this code
editText.setEnabled(false);
Suppose Your editText is empty then check like this
if(editText.getText().toString.isEmpty()){
editText.setEnabled(false);
}
First you set a :-
edittext.setFocusable(false);
edittest.setFocusableInTouchMode(false);
OR
set android:focusable="false" in XMl file
<EditText
android:id="#+id/EditTextInput"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:gravity="right"
android:cursorVisible="true">
</EditText>
Then in edittext's OnStateChangeListener you going to android:focusable="true" your next Edittext
editText1.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {}
#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() != 0){
edittext2.setFocusable(true);
edittest2.setFocusableInTouchMode(true);
}
}
});
Hope this helps you.
Use this and in onTextChanged set the data in editText you will get the your desired results.
yourEditText.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) {
}
#Override
public void afterTextChanged(Editable editable) {
}
});
setEnabled false or true in afterTextChanged. do whatever you want according to your need
You can try something like this:
editText1.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) {
editText2.setEnabled(false);
editText2.setText(editText1.getText().toString());
}
#Override
public void afterTextChanged(Editable editable) {
}
});
Set text watcher to your editText, and make them enabled/disabled when one of them is typed.
It should be ok in this way.
Try this...
when the user wants to put data in one editText the other
automatically becomes read-only dynamically to show the result
Use text watcher to your EditText, and make other edit text enabled/disabled when user typed on first EditText
EditText editText1 = (EditText)findViewById(R.id.text1);
EditText editText2 = (EditText)findViewById(R.id.text2);
editText1 .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) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
editText2.setEnabled(false);
//calculate and display result of that entered data
editText2.setText("your result");
}
});

Android on "<" key up listener on an edit text?

I'm trying to make a function for when the "<"/less than key is pressed, but i cant seem to get it correctly. I tried to add onKey(View view, int i, KeyEvent event) with Log, so that it would log everytime the "<" key was pressed but no matter what nothing is logged. I set the on key listener on my edit text but it doesnt work. Help Please. Is there anything i must add?
postingET = (EditText) findViewById(R.id.postInput); postingET.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
Log.i("LOL", String.valueOf(view));
return false;
}
});
postingET.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) {
}
});
Change log to
Log.i("LOL", postingET.getText().toString());

How to know if an EditText has changed before save the data?

I have a Profile's form with some EditText like the name, address, city and so on. And I have a Button to save this data once you press it.
So I would like to know how can I check if there have been changes before make my app connect with the database and update it.
I've thought using a TextChangedListener() with some boolean on the onTextChanged() or afterTextChanged(), but I don't know exactly how to do that.
Any suggestion? Thank you very much!
I´ve tried the code below and it works for me. I have this right now:
public class ProfileActivity extends Activity {
TextView done_btn;
EditText local_court;
boolean hasChanges = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
done_btn = (TextView) findViewById(R.id.done_profile_btn);
local_court = (EditText)findViewById(R.id.input_local_court);
done_btn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
if(checkChanges()) {
//saveChanges();
finish();
Toast.makeText(getApplicationContext(), "Your changes have been saved", Toast.LENGTH_SHORT).show();
}
}
});
public boolean checkChanges() {
local_court.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
hasChanges = true;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
return hasChanges;
}
}
I guess I should make the same with the other EditText.
Thank you everyone!
If your goal is just to check if something has changed at all, just check the current EditText value to what was before.
But if you want to know if the text has been touched, even reverted back to original, do as below.
EditText etext = (EditText) view.findViewById(R.id.editTxt);
etext.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s,
int start, int before,
int count) {
//Set your boolean here to true
}
#Override
public void beforeTextChanged(CharSequence s,
int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
}
);

Categories

Resources