Adding value on multiple EditText and getting the Total on every textchange - java

How can I sum all the total of my multiple EditText without using a Button but only on TextWatcher's onTextChanged() method. assuming this is my layout:
EditText1 = 5
EditText2 = 5
EditText3 = 5
EditText4 = 5
Total = 20
and so on
and getting the total of it?. the total should be CHANGING when the EditText's value is changing.
I have read this answer. but I can't execute it well on my program.
This is my Layout of it

You need to use a TextWatcher()
instead of using 5 TextWatcher() you can manage it using only a single TextWatcher()
Try this
Using below answer if all your 4 four edittext is not empty then it will calculate the sum of editext value
public class MainActivity extends AppCompatActivity {
EditText edtOne, edtTwo, edtThree, edtFour;
TextView tvResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtOne = findViewById(R.id.edtOne);
edtTwo = findViewById(R.id.edtTwo);
edtThree = findViewById(R.id.edtThree);
edtFour = findViewById(R.id.edtFour);
tvResult = findViewById(R.id.tvResult);
edtOne.addTextChangedListener(textWatcher);
edtTwo.addTextChangedListener(textWatcher);
edtThree.addTextChangedListener(textWatcher);
edtFour.addTextChangedListener(textWatcher);
}
TextWatcher textWatcher = 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) {
if (!TextUtils.isEmpty(edtOne.getText().toString().trim())
|| !TextUtils.isEmpty(edtTwo.getText().toString().trim())
|| !TextUtils.isEmpty(edtThree.getText().toString().trim())
|| !TextUtils.isEmpty(edtFour.getText().toString().trim())
) {
int answer = Integer.parseInt(edtOne.getText().toString().trim()) +
Integer.parseInt(edtTwo.getText().toString().trim()) +
Integer.parseInt(edtThree.getText().toString().trim()) +
Integer.parseInt(edtFour.getText().toString().trim());
Log.e("RESULT", String.valueOf(answer));
tvResult.setText(String.valueOf(answer));
}else {
tvResult.setText("");
}
}
#Override
public void afterTextChanged(Editable editable) {
}
};
}
UPDATE
if you want to calculate value of all editext evenif your editext is empty than try below TextWatcher()
TextWatcher textWatcher = 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) {
if (!TextUtils.isEmpty(edtOne.getText().toString().trim())
|| !TextUtils.isEmpty(edtTwo.getText().toString().trim())
|| !TextUtils.isEmpty(edtThree.getText().toString().trim())
|| !TextUtils.isEmpty(edtFour.getText().toString().trim())
) {
int firtValue = TextUtils.isEmpty(edtOne.getText().toString().trim()) ? 0 : Integer.parseInt(edtOne.getText().toString().trim());
int secondValue = TextUtils.isEmpty(edtTwo.getText().toString().trim()) ? 0 : Integer.parseInt(edtTwo.getText().toString().trim());
int thirdValue = TextUtils.isEmpty(edtThree.getText().toString().trim()) ? 0 : Integer.parseInt(edtThree.getText().toString().trim());
int forthValue = TextUtils.isEmpty(edtFour.getText().toString().trim()) ? 0 : Integer.parseInt(edtFour.getText().toString().trim());
int answer = firtValue + secondValue + thirdValue + forthValue;
Log.e("RESULT", String.valueOf(answer));
tvResult.setText(String.valueOf(answer));
}else {
tvResult.setText("");
}
}
#Override
public void afterTextChanged(Editable editable) {
}
};

I'm going to tell you how to do it, but I won't post the solution as a total code.
First of all, define integers that is the amount of your edit text count. If there is 4 edit texts, define 4 integers with like int first = 0, second = 0, third = 0, fourth = 0;
Then, add separate text watchers to your edit texts, and on your afterTextChanged methods, get the integer value from the string by using Integer.parseInt(Editable s.getText.toString()) and make sure the input is convertable, otherwise you will get a NumberFormatException. Then, assign this value to the related edit text, for example on your first edit text use first = Integer.parse(s.getText().toString()).
Create a function that uses these variables to display on a textview. For instance:
private void showResult() {
textView.setText(String.valueOf(first + second + third + fourth));
}
Then, at every afterTextChanged methods call this function to display the total amount.

Related

Display automatically an Integer value from Edit Text (entered by the user) to Text View without any actions (such as onButtonClick) in Android

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

How can I modify the input of multiple EditTexts at the same time, as I only modify one?

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!

Can I use The same TextWatcher on different EditText widgets

I have a form. I want to display a calculation in "live time" when the user enters different values into some int fields. I made my Activity implement the TextWatcher interface and set a listener on 3 different EditText fields but it appears the Textwatcher only detects the first EditText declared in the Activity's code.
You can see from the code below, I'm trying to grabe a few fields, convert them to ints and display the output in an EditText field at the bottom of the form. Where am I going wrong? Do I need to implement a textWatcher individually on all of the EditText fields involved? That would be a rather verbose solution making my code a lot longer than I would like
public class NewStageFormActivity extends AppCompatActivity implements TextWatcher{
Context mContext;
EditText mStageName, mPaperTargets, mHitsPerTarget, mSteelTargets, mSteelNPMs, mOutput;
Spinner mScoringType, mStrings;
CheckBox mNoShoots, mNPMs;
Button mSaveButton;
Match mGlobalMatch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stage_form);
mContext = this;
mGlobalMatch = GlobalMatch.getMatch();
mStageName = (EditText)findViewById(R.id.stage_name_et);
mPaperTargets = (EditText)findViewById(R.id.paper_targets_et);
mHitsPerTarget = (EditText)findViewById(R.id.hits_per_target_et);
mSteelTargets = (EditText)findViewById(R.id.steel_targets_et);
mSteelNPMs = (EditText)findViewById(R.id.steel_npm_et);
mScoringType = (Spinner)findViewById(R.id.scoring_type_spinner);
mStrings = (Spinner)findViewById(R.id.strings_spinner);
mNoShoots = (CheckBox)findViewById(R.id.no_shoots_cb);
mNPMs = (CheckBox)findViewById(R.id.npm_cb);
mSaveButton = (Button)findViewById(R.id.save_button);
mOutput = (EditText)findViewById(R.id.output_et);
// paper * hitsPer + steel
mPaperTargets.addTextChangedListener(this);
mSteelTargets.addTextChangedListener(this);
mSteelTargets.addTextChangedListener(this);
mSaveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(mStageName.getText().toString().equals("") || mPaperTargets.getText().toString().equals("") ||
mHitsPerTarget.getText().toString().equals("") || mSteelTargets.getText().toString().equals("") ||
mSteelNPMs.getText().toString().equals("")){
Toast.makeText(mContext, "You must fill in all form fields", Toast.LENGTH_SHORT).show();
} else {
String name = mStageName.getText().toString();
String type = mScoringType.getSelectedItem().toString();
int strings = Integer.valueOf(mStrings.getSelectedItem().toString());
int paperTargets = Integer.valueOf(mPaperTargets.getText().toString());
int hitsPerTarget = Integer.valueOf(mHitsPerTarget.getText().toString());
boolean noShoots;
boolean npms;
if(mNoShoots.isChecked()){
noShoots = true;
} else {
noShoots = false;
}
if(mNPMs.isChecked()){
npms = true;
} else {
npms = false;
}
int steelTargets = Integer.valueOf(mSteelTargets.getText().toString());
int steelNPMs = Integer.valueOf(mSteelNPMs.getText().toString());
MatchStage matchStage = new MatchStage(name, type, strings, paperTargets, hitsPerTarget,
noShoots, npms, steelTargets, steelNPMs);
mGlobalMatch.getStages().add(matchStage);
String jsonString = new Gson().toJson(mGlobalMatch);
MatchHelper.updateFile(mContext, MatchHelper.createFileName(mGlobalMatch.getMatchId()),
jsonString);
Intent intent = new Intent(mContext, StagesListActivity.class);
startActivity(intent);
}
}
});
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
int paper = Integer.valueOf(mPaperTargets.getText().toString());
int hitsPer = Integer.valueOf(mHitsPerTarget.getText().toString());
int steel = Integer.valueOf(mSteelTargets.getText().toString());
int minRound = (paper * hitsPer) + steel;
int points = minRound * 5;
mOutput.setText("Minimum rounds: " + (minRound) + "\t\t Points: " + points);
}
#Override
public void afterTextChanged(Editable editable) {
}
}
In my experience I've had issues with using the same TextWatcher on multiple EditText. You could get around this by creating a method that produces a new instance of TextWatcher for each EditText so your code isn't all verbose. Try something like this:
Get rid of implements TextWatcher for your Activity and it's associated methods. Implement a method createTextWatcher():
private TextWatcher createTextWatcher() {
return new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
// Copy your original code
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
// Copy your original code
}
#Override
public void afterTextChanged(Editable editable) {
// Copy your original code
}
};
}
Now to use it like this:
mPaperTargets.addTextChangedListener(createTextWatcher());
mSteelTargets.addTextChangedListener(createTextWatcher());
The most up-voted answer on #Natan Felipe's link also demonstrates using one instance of TextWatcher per EditText.

Set EditText filter to numbers within a custom range

I am looking for a way to limit the numbers I enter into the EditText field, but I am encountering some obstacles.
I have already thoroughly researched for a solution to my problem, which I will define specifically below.
I want to create 4 different EditText fields in which each accepts the following ranges: (1, 24); (80, 200); (1, 999); (40, 70).
These, for simplicity, will not be decimals (or doubles/floats/longs) but only integers.
I have looked into the solutions provided by the following links, and have provided their shortcomings.
Android: Limiting EditText to numbers
This solution only tells me how to limit the entered text to numerical data only. It does not provide ranges.
Is there a way to define a min and max value for EditText in Android?
The accepted solution does accomplish the goal of setting the range, but the problem is that it only works for the ranges (1, 24) and (1, 999) due to its implementation. The problem is that if I look for values in the intervals (40, 70) or (80, 200), I will start by entering one digit at a time, so this does not work. It will deny the single digit input, which makes it non-user friendly.
How to limit the text in numbers only from 0-59 in Edit Text in Android?
I believe the accepted solution here has the same problem as the one above, since it takes one digit at a time. I considered using the same method under afterTextChanged instead on onTextChanged, but to no avail.
Number range on an edittext - only want numbers between 1 and 10
This solution involves a button click to evaluate whether the number falls in the given range, so this would be considered an "after-the-fact" solution. I need an EditText that rejects the user's input in real time.
Your assistance is greatly appreciated and will probably help resolve the problems that many others have apparently had (reading the comments, others seem to want ranges that don't start/end in single-digit numbers).
Use a Textwatcher,
Here I have one edittext and I am allowing a user if he enter a number in the range of 1-24
public class MainActivity extends AppCompatActivity {
EditText et;
int num1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et= (EditText) findViewById(R.id.edit_text);
et.addTextChangedListener(textWatcher);
}
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) {
if(et.getText().length()>0) {
int num = Integer.parseInt(et.getText().toString());
if (num>=1 && num<=24)
{
//save the number
num1=num;
}
else{
Toast.makeText(MainActivity.this,"Please enter the code in the range of 1-24",Toast.LENGTH_SHORT).show();
et.setText("");
num1=-1;
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
};
}
Here is the xml file
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/edit_text"
android:inputType="number"
/>
At the end dont forgot to check that
if(num1==-1)
{
Toast.makeText(MainActivity.this,"Please fill all the fields",Toast.LENGTH_SHORT).show();
}
The best answer I've found so far is based on the solution at the following link, but it has one shortcoming: (https://stackoverflow.com/a/28743065/5906258)
The shortcoming is that once we move away from inserting our input into the EditText, the values are retained by the EditText box (instead of purged).
My (edited) code is as follows:
First class InputFilterMax:
package test;
import android.text.InputFilter;
import android.text.Spanned;
// more imports
public class InputFilterMax implements InputFilter {
private int max;
private Context context;
public InputFilterMax(Context con, int max) {
this.max = max;
this.context = con;
}
public InputFilterMax(Context con, String max) {
this.max = Integer.parseInt(max);
this.context = con;
}
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
String replacement = source.subSequence(start, end).toString();
String newVal = dest.toString().substring(0, dstart) + replacement +dest.toString().substring(dend, dest.toString().length());
int input = Integer.parseInt(newVal);
if (input<=max)
return null;
} catch (NumberFormatException nfe) {
Toast.makeText(context, "Number not accepted! Must be below or equal to " + max, Toast.LENGTH_SHORT).show();
return null;
}
return "";
}
}
And second class OnFocusChangeListenerMin:
package test;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnFocusChangeListener;
// more imports
public class OnFocusChangeListenerMin implements OnFocusChangeListener {
private int min;
private Context context;
public OnFocusChangeListenerMin(Context con, int min) {
this.min = min;
this.context = con;
}
public OnFocusChangeListenerMin(Context con, String min) {
this.min = Integer.parseInt(min);
this.context = con;
}
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus) {
String val = ((EditText)v).getText().toString();
if(!TextUtils.isEmpty(val)){
if(Integer.valueOf(val)<min){
Toast.makeText(context, "Number not accepted! Must be above or equal to " + min, Toast.LENGTH_SHORT).show();
}
}
}
}
}
Then in the Activity I use the following to apply the filter and listener:
timeEdit = (EditText)findViewById(R.id.query_time_frame);
timeEdit.setFilters(new InputFilter[]{new InputFilterMax(getApplicationContext(), 24)}); // max limit on time
timeEdit.setOnFocusChangeListener(new OnFocusChangeListenerMin(getApplicationContext(), 1)); // min limit on time
If anyone can help me fix the last problem I'm having, it would be greatly appreciated.
You can try with afterTextChanged callback of TextWatcher. See how I implemented it.
private TextWatcher tollTextWatcher = 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) {
if (editable.length() > 0) {
int val = Integer.valueOf(editable.toString());
if (val > MAX_VALUE) {
edit_toll.setText("");
edit_toll.setError("Rs.1 - Rs.500");
}
}
}
};

How do I disable 2 buttons if a number field is empty

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(...){..}

Categories