I have 2 buttons and 1 number field, if I press a button without something in the field, it crashes, so what I want to do is disable the buttons unless the number field has something in it, I have looked around for an answer but either they aren't relevant, or I'm not sure how it would fit into my code, here are the two onClick functions for each button. Thanks
public void toPounds(View view){
EditText amount = (EditText)findViewById(R.id.amount);
Double omrAmount = Double.parseDouble(amount.getText().toString());
Double gbrAmount = omrAmount * 1.79;
Toast.makeText(getApplicationContext(), "£" + gbrAmount.toString(), Toast.LENGTH_LONG).show();
}
public void toRiyals(View view){
EditText amount = (EditText)findViewById(R.id.amount);
Double gbrAmount = Double.parseDouble(amount.getText().toString());
Double omrAmount = gbrAmount / 1.79;
Toast.makeText(getApplicationContext(), omrAmount.toString() + " Riyals", Toast.LENGTH_LONG).show();
}
yourField.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)
button1.setEnabled(false)
else
button1.setEnabled(true)
}
});
link
If you want to disable buttons if edit text is empty then you can do the following :
EditText amount = (EditText)findViewById(R.id.amount);
Button button = (Button) findViewById(R.id.button1);
if(amount.getText().toString().isEmpty()){
button.setEnabled(false);
}
amount.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)
button1.setEnabled(false)
else
button1.setEnabled(true)
}
});
Not specifically an answer to your question, but generally speaking you would want to add some sort of check before you call your code which now crashes your application. It's not a good idea to to have code which crashes your app lingering around.
Maybe make a method like: isMyEditTextValid(...){..}
Related
Trying to get an integer from Edit Text entered by the user(such as Total Amount) and to display it by multiplying with value(such as 5%) and display it using TextView automatically.
For the 1st part i.e. simply displaying the integer from EditText to TextView got NumberFormatException Error.
'''
temp = (Integer.parseInt(editText.getText().toString()));
textView.setText(temp);
'''
And for the second part i.e. automatically displaying the value from EditText to TextView, no idea how to approach.
Just use textwatcher and put the logic in it. Just make sure change the id of edittext and textview
et.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) {
String value = s.toString();
double outputValue = Integer.parseInt(value) * 0.05;
textView.setText(String.valueOf(outputValue));
}
});
Make sure in edittext that it only capture the numerical value.
you could try this approach
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) {
String userInputText = s.toString();
try {
val userInputAsNumbger = userInputText.toInt();
}catch (e:NumberFormatException){
print(e.message)
}
}
});
to ensure it doesn't error
I have multiple EditTexts and I want to change the input of all of them at the same time, as I modify only one.(all of them take decimal numbers as input)
I stored the EditTexts in an array named 'editTexts'.
Here's what I tried
//Set the listener for each element
for (int i=0; i<editTexts.length; i++) {
final int finalI = i;
editTexts[i].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 the editText which is currently edited is empty, set the input for all the rest to be '0.0'
if (editTexts[finalI].getText().toString().trim().length() == 0) {
for(EditText e : editTexts) {
if (e == editTexts[finalI])
continue;
e.setText("0.0");
}
} else {
float no = Float.parseFloat(s.toString() + "");
//Set the input of all the other editTexts to be the decimal number entered, multiplied by 2
for(EditText e : editTexts){
if(e == editTexts[finalI])
continue;
e.setText(no*2+"");
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
})
}
In this case the multiplication coefficient is just an example, it's not always gonna be 2. I used it just to test it out.
For some reason, when I change the input value, the app freezes.
Any help? Thanks!
Use LiveData to store your user input values.
Once it's value changes you can set value to each EditText. I think it is an easy way to implement.
Try it like this:
// et_x1, et_x2 and et_x3 are ids of EditTexts
//set inputType for all EditTexts as numberDecimal
EditText editText1 = findViewById(R.id.et_x1);
final EditText editText2 = findViewById(R.id.et_x2);
final EditText editText3 = findViewById(R.id.et_x3);
editText1.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) {
String value = s.toString();
double x;
if (!value.equals("")) {
x = Double.parseDouble(value);
} else {
x = 0.0;
}
editText2.setText(Editable.Factory.getInstance().newEditable((String.valueOf(Math.pow(x, 2)))));
editText3.setText(
Editable.Factory.getInstance().newEditable((String.valueOf(Math.pow(x, 3)))));
}
#Override
public void afterTextChanged(Editable s) {
}
});
Hope it helps you!
Lets assume I have 2 EditText objects inp1 and inp2. If I enter something into inp1 I want it to appear in inp2 and vice versa. Changes made in either should change the other as well. i actually want two EditText objects to input numbers in bases 10 and 2 respectively. And when I enter a binary number I want its equivalent decimal number to appear in the other EditText and vice versa without the use of any button or anything. Is there anything equivalent to the onClick attribute of buttons for EditText? Which might call a function automatically whenever there is a change in the EditText's text.
I hope I could make my question clear.
Thank You.
You need to use the TextWatcher on both fields. The answer to this question basically does what you describe
you can use TextWatcher like this
tagNameEditText.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) {
// set text or result in other EditText here
}
#Override
public void afterTextChanged(Editable s) {
}
});
In this Listener in onTextChanged() method you can set the text in other EditText
Use TextWatcher.
This is short code:
private final TextWatcher edit_one_Watcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
// enter your logic here
//and print in second edittext
}
public void afterTextChanged(Editable s) {
}
};
And
private final TextWatcher edit_second_Watcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
// enter your logic here
//and print in first edittext
}
public void afterTextChanged(Editable s) {
}
};
Note: use boolean / flag to ignore autotextchange.
.i.e. boolean ignoreFirstTextChange = true;
.i.e. boolean ignoreSecondTextChange = true;
I am doing a chat app and got stocked on how to make textWatcher which will push on the firebase data structure under user-typing
. I want to push a data structure wherein on the data structure you will see if the user is typing. when the user is typing the data structure under user-typing is true. if the user is not typing then it will become false. i tried this code but it seems wrong because every time i run the program. When I click the ediText. it will automatically make a data structure key for a user
final Firebase test = firebase.child("room-typing").push();
test.setValue("true");
final EditText editText = (EditText) findViewById(R.id.editText);
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) {
if (s == editText) {
firebase.child("room-typing").child(test.getKey()).child("test").setValue("true");
} else {
firebase.child("room-typing").child(test.getKey()).child("test").setValue("false");
}
}
});
You're creating that new key yourself, by calling push(). From the documentation for push():
Generates a new child location using a unique key and returns a Firebase reference to it.
I added some comments to you code, to mark where things happen:
// This next line creates a new key
final Firebase test = firebase.child("room-typing").push();
test.setValue("true");
final EditText editText = (EditText) findViewById(R.id.editText);
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) {
if (s == editText) {
// This next line uses the new key you created above
firebase.child("room-typing").child(test.getKey()).child("Onediver").setValue("true");
} else {
// As does the next line here
firebase.child("room-typing").child(test.getKey()).child("Onediver").setValue("false");
}
}
});
To prevent the creation of a new child, you should not call push, but depend on a known child, such as:
final Firebase test = firebase.child("room-typing").child("jaymee");
There are 2 ways you can do this. An easy way and there is an elegant way.
For elegant way look into: http://reactivex.io/documentation/operators/debounce.html
Here's the easy way:
Create somewhere a custom countdown timer:
public class MyCountDownTimmer extends CountDownTimer {
public MyCountDownTimmer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override public void onTick(long l) {
}
#Override public void onFinish() {
databaseReference.child("room-typing").child(room_name).child(user_id_or_name).setValue("false");
isTyping = false;
}
}
Declare your countdown timer
private MyCountDownTimmer isTypingTimmer = new MyCountDownTimmer(1000, 1000);
private boolean isTyping = false;
editText_message.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) {
isTypingTimmer.cancel();
isTypingTimmer.start();
if (!isTyping) {
databaseReference.child("room-typing").child(room_name).child(user_id_or_name).setValue("true");
isTyping = true;
}
}
});
I tried the following code, but android doesn't let me do that, as I'd enter into an infinite loop.
mEditText = (EditText) getActivity().findViewById(R.id.input_content);
mEditText.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) {
//I want to format the already existing text in s in a certain way as the user is typing
mEditText.setText(s.toString() + " \n");
}
});
Please any ideas would be very helpful. Thanks
3 possible solutions :
Check for the carriage return presence in the string
Like this :
mEditText = (EditText) getActivity().findViewById(R.id.input_content);
mEditText.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)
{
//I want to format the already existing text in s in a certain way as the user is typing
if (s.toString().charAt(s.length() - 1 ) != '\n')
{
mEditText.setText(s.toString() + " \n");
}
}
});
Not the best solution, according to what's in your input string
Do it in beforeTextChanged
Like this :
mEditText = (EditText) getActivity().findViewById(R.id.input_content);
mEditText.addTextChangedListener(new TextWatcher()
{
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
//I want to format the already existing text in s in a certain way as the user is typing
mEditText.setText(s.toString() + " \n");
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void afterTextChanged(Editable s) {}
});
Cancel the listener, temporarily
Like this :
final TextWatcher tw = 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)
{
//I want to format the already existing text in s in a certain way as the user is typing
mEditText.removeTextChangedListener(tw);
mEditText.setText(s.toString() + " \n");
mEditText.addTextChangedListener(tw);
}
});
mEditText = (EditText) getActivity().findViewById(R.id.input_content);
mEditText.addTextChangedListener(tw);
You are most likely entering an infinite loop because you are changing the text in public void afterTextChanged(Editable s) which then causes the method to be called again.
The best solution would be to change the text in one of the other methods, or on the loss of focus of the editable. See View.OnFocusChangeListener for more details on this.
Here is an example:
textView.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus) {
textView.setText(s.toString() + " \n");
}
}
});