I am creating a calculator app in android. The issue is how can I check for existence of two decimals in a single numeric value . Currently my calculator allows inputs such as 1.2.3
which is illegal . It must allow a decimal if an operator has been used. Eg 1.1+2.2
is legal but 1.1.1+2.2
isn't. Here is my code for decimal handling:
public class TrialCalculator extends AppCompatActivity implements Button.OnClickListener {
Button btn1, btn2, btnBack, btn3, btn4, btn5, btn6, btn7, btn8, btn9, btn0, btnPlus, btnMinus, btnMul, btnDiv, btnEquals, btnClear, btnDecimal, btnPercent;
EditText calcResult;
double number = 0;
private char opcode = '1';
private void handleDecimal() {
if (opcode == 0) clear();
if (calcResult.getText() == null) {
calcResult.setText("0.");
calcResult.setSelection(2);
} else {
String txt = calcResult.getText().toString();
if (txt.lastIndexOf(".")<txt.length()-1) {
calcResult.append(".");
}
}
}
}
I am calling the buttonDot
from onClick
Method.
One solution is to have a flag which keeps track of the decimal:
class MyCalculator {
private hasDecimal = false;
// ...
}
Set this flag to true
the first time that the user types a decimal. Then check the flag to see if a decimal has been previously typed.
Of course, this only works if you are responding to each key press directly rather than getting the entire input from a EditText
after the user has typed the entire number.
You can use regex with matches
function
\\\\d*
mean match zero or more digits
(\\\\.\\\\d+)?
match a .
followed by one or more digits , ?
mean matches between zero or one times of given group
Regex Demo : note with matches
function in java, we don't need ^
start and $
ending anchors
Code
if (txt.matches("\\d*(\\.\\d+)?")) {
// number has one decimal
}
else{
// number has more than one decimal
}
Note: if you don't want to allow values like .5
then use \\\\d+
instead of \\\\d*
as
\\\\d+(\\\\.\\\\d+)?
As suggested by @Code-Apprentice , if you want to accept values like 4343.
etc you can use
\\d*(\\.\\d*)?
Using text watcher
calcResult.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) {
boolean flag = s.toString().matches("\\d*(\\.\\d*)?");
if(!flag){
// calcResult.setError...
// you display a toast
}
}
});
Update : To match multiple values with operators , you can use
(\\d*(\\.\\d*)?([+\\-*%\\]|$))*
Test Cases
String pat="(\\d*(\\.\\d*)?([+\\-*%\\]|$))*";
System.out.println("4.5-3.3+3.4".matches(pat));
System.out.println(".5".matches(pat));
System.out.println("4".matches(pat));
System.out.println("4.5.5-4.4".matches(pat));
System.out.println("4.44.5+4.4.4".matches(pat));
System.out.println("4.".matches(pat));
Output :
true
true
true
false
false
true
lastIndexOf
returns -1 if the character is not found in the string. So your condition txt.lastIndexOf(".")<txt.length()-1
is always true
. You could change it to
txt.lastIndexOf(".") == -1
To check for existence of two decimals in a single no then split the string by decimal.
for eg,
String txt = calcResult.getText().toString();
String[] decimals = txt.split("\\.");
if(decimals.length > 2) {
// txt contains more than 1 decimal.
// Your logic ..
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.