I have an activity which contain two edit text and have a TextWatcher in that activity which is implemented separately. I want to make a single class which implements TextWatcher and that that TextWatcher in that edit text. How can I do that
code:-
private TextWatcher getmWatcher = 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) {
checkFieldsForEmpty();
}
};
private TextWatcher mWatcher = 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) {
checkFieldsForEmpty();
}
};
m_InputMobile = (EditText) findViewById(R.id.input_mobile);// finding Id of Mobile Number edit text
m_InputMobile.addTextChangedListener(getmWatcher);
m_InputPassword = (EditText) findViewById(R.id.input_password);// finding Id of assword editText
m_InputPassword.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);// defining password edit Tect Input type
There is two ways you can do this.
First
TextWatcher textWatcher = 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 (m_InputMobile.getText().hashCode() == s.hashCode()) {
checkFieldsForEmpty();
}
else if (m_InputPassword.getText().hashCode() == s.hashCode()) {
checkFieldsForEmpty();
}
}
};
m_InputMobile = (EditText) findViewById(R.id.input_mobile);
m_InputMobile.addTextChangedListener(getmWatcher);
m_InputPassword = (EditText) findViewById(R.id.input_password);
m_InputPassword.addTextChangedListener(getmWatcher);
or make a custome TextWatcher class
Second
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_InputMobile = (EditText) findViewById(R.id.input_mobile);
m_InputMobile.addTextChangedListener(new CustomTextWatcher(m_InputMobile));
m_InputPassword = (EditText) findViewById(R.id.input_password);
m_InputPassword.addTextChangedListener(new CustomTextWatcher(m_InputPassword));
}
private class CustomTextWatcher implements TextWatcher {
private EditText mEditText;
public CustomTextWatcher(EditText e) {
mEditText = e;
}
#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) {
checkFieldsForEmpty();
}
}
For more details visit this Question.
Happy Coding.
Multiple edittext Intialization & Setting TextChangeListener
for(int i=0;i<editTexts_ids.length;i++)
{
editTexts[i] = (EditText)view.findViewById(editTexts_ids[i]);
editTexts[i].addTextChangedListener(this);
textInputLayouts[i]= (TextInputLayout)view.findViewById(textInputLayouts_ids[i]);
//Log.e("EditText["+i+"]",""+editTexts[i].getId());
}
In afterTextChanged Method
#Override
public void afterTextChanged(Editable editable) {
for(int i=0;i<editTexts_ids.length;i++) // Disable Error AFter Entered Text
{//not include Mobile Number Name,S/o, Nominee Edittexts
if (editTexts[i].getText().hashCode() == editable.hashCode())// Checking
{
//Mobile Number VAlidation At Runtime
if(i==11)
{
if(Utils.Mobile_NumberValidation(editable.toString()))
{
textInputLayouts[i].setError("");
return;
}
else
{
textInputLayouts[i].setError("Invalid Mobile Number (should start with 7 or 8 or 9) , Length 10 digits");
return;
}
}
if (i == 4) { // for Name
if(!Utils.Name_Validation(editable.toString())) {
textInputLayouts[4].setError("Invalid Person Name (Special Symbols(#,!,$ .etc), DOT (.) are not allowed)");
return;
}else
{
textInputLayouts[4].setError("");
return;
}
}
if (i == 5) { //for S/o,D/o,W/o
if(!Utils.Name_Validation(editable.toString())) {
textInputLayouts[5].setError("Invalid Person Name (Special Symbols(#,!,$ .etc), DOT (.) are not allowed)");
return;
}else
{
textInputLayouts[5].setError("");
return;
}
}
if (i == 9) { //for S/o,D/o,W/o
if(!Utils.Name_Validation(editable.toString())) {
textInputLayouts[9].setError("Invalid Person Name (Special Symbols(#,!,$ .etc), DOT (.) are not allowed)");
return;
}else
{
textInputLayouts[9].setError("");
return;
}
}
if (!editable.toString().trim().isEmpty()) {
textInputLayouts[i].setError("");
return;
}
}
}
}
Simply create a TextWatcher object and pass it into the addTextChangeListener like this :
TextWatcher textWatcher = 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) {
checkFieldsForEmpty();
}
};
m_InputMobile.addTextChangedListener(textWatcher);
Related
I have an edit text to fill amount. So, I added text watcher, but I don't want user to "0000000..." if user will continuously press "0000..." instead it should show only one time '0' like Calculator
How can I do that?
private void setAmount() {
etAmount.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() == 1) {
if (s.toString().equals("0")) {
etAmount.setText("0");
}
}
//Not working
}
#Override
public void afterTextChanged(Editable s) {}
});
}
I think, my logic is also wrong, because when I enter single input and check s.length, and after et.setText("0"), it will go to infinite loop.
Try this:
etAmount.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) {
String text = s.toString();
if (text.length() == 2 && text.charAt(0) == '0') {
etAmount.setText(text.substring(1));
etAmount.setSelection(1);
}
}
});
You can do it like this:
etAmount.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) {}
#Override
public void afterTextChanged(Editable s) {
if (s.length() == 2) {
if (s.toString().startsWith("00")) {
etAmount.setText("0");
}
}
}
});
I have three Edittext named as mobile,password,email for these i was implemented seperate Textwatcher for them, But I want to make single Textwatcher for multiple Edittext.How can I do that to acheive.
code:-
private final TextWatcher m_EmailWatcher = 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) {
checkForEmptyField();
}
#Override
public void afterTextChanged(Editable s) {
/*check whether SoftKeyPad open or hide*/
m_MainLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int heightDiff = m_MainLayout.getRootView().getHeight() - m_MainLayout.getHeight();
//noinspection StatementWithEmptyBody
if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
} else {/*if hide then clear focus from Password Edit text*/
m_EmailEditText.clearFocus();
m_Email = m_EmailEditText.getText().toString().trim();
if (isValidEmail(m_Email) && m_Email.split("#")[0].length() <= 64 && (m_Email.split("#")[1].length() >= 2 && m_Email.split("#")[1].length() <= 255)) {
} else {
m_EmailEditText.setError("Please enter valid Email Id");
}
}
}
});
}
};
private final TextWatcher m_PassWordWatcher = 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) {
checkForEmptyField();
}
#Override
public void afterTextChanged(Editable s) {
}
};
private final TextWatcher m_MobileWatcher = 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) {
checkForEmptyField();
}
#Override
public void afterTextChanged(Editable s) {
}
};
Create a separate Class extending TextWatcher.
public class CustomTextWatcher implements TextWatcher {
private EditText editText;
private Context context;
private int value;
public CustomTextWatcher(Context context, EditText et, int val){
this.context = context;
this.editText = et;
this.value = val;
}
#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.toString().length() > 0){
if(value == 0){
//Email
}
else if(value == 1){
//Mobile Number
}
else if(value == 2){
//Password
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
}
Whenever you want to apply a TextWatcher to an EditText do it like this.
CustomTextWatcher cew1 = new CustomTextWatcher(this, emailEditText, 0);
emailEditText.addTextChangedListener(cew1);
I have an activity in which I have mobile edit text what I want when user enter mobile number I want to add "+91" before number and when user delete full number I want to delete "+91" also .How can I do that
TextWatcher m_MobileWatcher = 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().contains("+91")) {
m_InputMobie.setText("+91" + s.toString());
Selection.setSelection(m_InputMobie.getText(), m_InputMobie.getText().length());
}
}
};
Try below code this is working fine, I have checked.
TextWatcher m_MobileWatcher = 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) {
String text_value = m_InputMobie.getText().toString().trim();
if(text_value.equalsIgnoreCase("+91"))
{
m_InputMobie.setText("");
}else
{
if(!text_value.startsWith("+91") && text_value.length()>0) {
m_InputMobie.setText("+91" + s.toString());
Selection.setSelection(m_InputMobie.getText(), m_InputMobie.getText().length());
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
};
I have two TextViews EditText and have assigned each on a TextChangedListener, which reference each other, changing the text of the other textview. Specifically:
rateText.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(!rateText.getText().toString().equals("")) {
float price = Float.parseFloat(priceText.getText().toString());
float rate = Float.parseFloat(rateText.getText().toString());
// REFERNCES THE OTHER TEXT
amountText.setText(Float.toString(price / rate));
} else {
amountText.setText("");
}
}
});
amountText.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(!rateText.getText().toString().equals("")) {
float price = Float.parseFloat(priceText.getText().toString());
float amount = Float.parseFloat(amountText.getText().toString());
// REFERNCES THE OTHER TEXT
rateText.setText(Float.toString(price / amount));
} else {
rateText.setText("");
}
}
});
This results in an infinite loop, because each listener causes the other one to trigger. How can i prevent this without needing a button or something?
You could hold the TextWatchers in fields and use a static method to set the text "silently" without notifying the listeners like this:
private TextWatcher rateWatcher; //hold watchers in fields
private TextWatcher amountWatcher;
//...
void yourMethodOrCallback() { //whatever
//...
amountWatcher = 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 (!rateText.getText().toString().equals("")) {
float price = Float.parseFloat(priceText.getText().toString());
float amount = Float.parseFloat(amountText.getText().toString());
// REFERNCES THE OTHER TEXT
setTextSilently(amountText, amountWatcher, Float.toString(price / amount));
} else {
setTextSilently(rateText, rateWatcher, "");
}
}
};
rateWatcher = 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 (!rateText.getText().toString().equals("")) {
float price = Float.parseFloat(priceText.getText().toString());
float rate = Float.parseFloat(rateText.getText().toString());
// REFERNCES THE OTHER TEXT
setTextSilently(amountText, amountWatcher, Float.toString(price / rate));
} else {
setTextSilently(amountText, amountWatcher, "");
}
}
};
rateText.addTextChangedListener(rateWatcher);
amountText.addTextChangedListener(amountWatcher);
}
private static void setTextSilently(EditText editText, TextWatcher textWatcher, CharSequence text) {
editText.removeTextChangedListener(textWatcher); //removing watcher temporarily
editText.setText(text); //setting text
editText.addTextChangedListener(textWatcher); //readding watcher
}
I would agree with #Lotharyx's suggestion to try using a boolean first. The boolean variable should only have to be final if declared in the same scope as the method where you are adding these TextWatchers, otherwise you can use an instance variable (doesn't have to be static).
Another thing you could try is to remove the TextWatcher before the body of code in afterTextChanged(), and add it again after you have call setText() on the other EditText. But this would also require you to make the TextWatcher objects instance variables or declare them as final.
#Override
public void afterTextChanged(Editable s) {
rateText.removeTextChangedListener(rateTextListener);
if(!rateText.getText().toString().equals("")) {
float price = Float.parseFloat(priceText.getText().toString());
float amount = Float.parseFloat(amountText.getText().toString());
// REFERNCES THE OTHER TEXT
rateText.setText(Float.toString(price / amount));
} else {
rateText.setText("");
}
rateText.addTextChangedListener(rateTextListener);
}
public class SampleActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_datepicker);
final EditText text1 = (EditText) findViewById(R.id.text1);
final EditText text2 = (EditText) findViewById(R.id.text2);
text1.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try {
int total = Integer.parseInt(s.toString()) + 1;
text2.setText(String.valueOf(total));
}catch (Exception e){
e.printStackTrace();
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void afterTextChanged(Editable s) {
}
});
text2.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try {
int total = Integer.parseInt(s.toString()) + 2;
text1.setText(String.valueOf(total));
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
}
Hi I am facing one problem with multiple edit text updating parallel.If i enter value in first edit-text, the second edit text changed.Same in second edittext. But the key listener of cursor in edit-text has problem. i am unable to get the cursor.How to solve this problem?
I don't get what you are doing (or trying to do).
In the onTextChanged for text1 you are triggering the onTextChanged for text2. Seems like infinite text change listeners being triggered here.
The logic for what is happening ->
Suppose the user types in the character 1 into text1. total is now 2. Now you set text2 as total which is 2. This in turn triggers the Text Change Listener for text2. Now total is 2+2=4. You now set 4 as the text for text1. This in turn triggers the Text Change Listener for text1.
Seems like a never ending infinite loop to me. This is the reason you are getting a StackOverflowError (lol) What did you actually want to do?
Not really sure about what might solve that problem (I don't have a working copy of Android Studio at hand), but moving the block to afterTextChanged might do it.
You can try this way. TextWatcher will update the values to second EditText through Handler through the method afterTextChanged.
EditText text1;
StringBuffer previousChar=new StringBuffer();
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
text1=(EditText)findViewById(R.id.editText);
text1.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(!previousChar.toString().equals(s.toString())){
Message msg=new Message();
msg.obj=s.toString();
localHandler.sendMessage(msg);
previousChar=new StringBuffer(s.toString());
Log.i("TAG", "TextEntered = "+s);
}
}
});}
The handler will be used to update the text in second EditText
private Handler localHandler = new Handler(){
public void handleMessage(Message msg) {
super.handleMessage(msg);
String value=(String)msg.obj;
text2.setText(value);
}
};
includeTW = 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) {
if(!(includedText.getText().toString().equals("")))
{
excludedText.removeTextChangedListener(excludeTW);
String included = includedText.getText().toString();
excludedText.setText(included); //////// Error Line
excludedText.addTextChangedListener(excludeTW);
}
}
};
excludeTW = 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) {
if(!(excludedText.getText().toString().equals(""))) {
includedText.removeTextChangedListener(includeTW);
String excluded = excludedText.getText().toString();
includedText.setText(excluded);
includedText.addTextChangedListener(includeTW);
}
}
};
includedText.addTextChangedListener(includeTW) ;
excludedText.addTextChangedListener(excludeTW);
This will give the solution exactly what i want.I am getting the value with the cursor moving in each edittext.
Remove TextChangeListener of another EditText when first one is in effective mode and add that after text change..
public class SampleActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_datepicker);
final EditText text1 = (EditText) findViewById(R.id.text1);
final EditText text2 = (EditText) findViewById(R.id.text2);
text1.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
**text2.addTextChangedListener(null);**
try {
int total = Integer.parseInt(s.toString()) + 1;
text2.setText(String.valueOf(total));
}catch (Exception e){
e.printStackTrace();
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void afterTextChanged(Editable s) {
**text2.addTextChangedListener(this);**
}
});
text2.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
text1.addTextChangedListener(null);
try {
int total = Integer.parseInt(s.toString()) + 2;
text1.setText(String.valueOf(total));
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s)
{
**text1.addTextChangedListener(this);**
}
});
}
}