textView wont display decimals - java

I am having an issue with my program, my textveiw will not display any decimals, heres the break down on whats happeneing. The user enters a number in a textEdit (Also how do i make the textedit only accept numbers AND a decimal point?) that number gets converted to a int, sent to my second activity, diveded by 3600, then displayed in a textveiw box. The issue is that when that number is displayed it has no decimal value, for example if its less than 1 it will not display anything, how can i go about fixing this? i need it to at least go to the 1000th place.
Here is my code one activity1:
public void sendMessage(View view) {
// Do something in response to button
Intent intent = new Intent(this, PayTracker.class);
// Gather text from text boxes
EditText editText = (EditText) findViewById(R.id.hourly_wage);
//Create String from text
String message1 = editText.getText().toString();
//Convert String to Int
int HW = 0;
try{
HW = Integer.valueOf(message1);
}
catch(NumberFormatException nfe){
//do something else here
//for e.g. initializing default values to your int variables
}
// Send Integers to PayTracker.java
intent.putExtra(MESSAGE_HW, HW);
// start new activity
startActivity(intent);
And then this is activity2 where the number needs to be displayed:
public void sendMessage(View view) {
// Receive messages from options page
Intent intent = getIntent();
int HW = intent.getIntExtra(Options.MESSAGE_HW, 0);
// Calculate pay per second
int PPS = 0;
PPS = (HW/3600);
// set textView
TextView textView = (TextView) this.findViewById(R.id.yourpay);
textView.setText(String.valueOf(PPS));
}
Any help would be appreciated! thanks!

Use doubles or floats. From what I see, everything should work except that you forgot that 5 divided by 2 as int is 2, and not 2.5.
so do as gtumca said and use doubles; longs are just bigger ints.
in other words...
activity1
try{
HW = Double.valueOf(message1);
}
activity 2
//double HW = intent.getIntExtra(Options.MESSAGE_HW, 0);
double HW = intent.getDoubleExtra(Options.MESSAGE_HW, 0);
// pay is rarely a round number
double PPS = HW / 3600;

that number gets converted to a int
Integers dont have decimals :)
As to the EditText only accepting numbers:
EditText, inputType values (xml)
Set one of those types to your EditText in the Layout xml like:
android:inputType="number"

You are using int as data type so you are getting int values only
double PPS = 0;
^^^^^^
instead of
int PPS = 0;

You shouldn't use float or double to keep numbers with such big precision. Float and double cannot represent decimal fractions exactly due to their internal representations. Please, check BigDecimal if you want 1000-digit precission(or more).

Related

How to change a double to a string

I have an app which shows a string in an EditText, this string is the result of the operation of two other doubles the user types in two different EditTexts.
The problem is that I want the result of the operation to be shown in the third EditText, but for that it has to be a string. Therefore I change the result by the toString method.
The problem starts here, I want the double that will be a string to have only one decimal. For that I used DecimalFormat and created the df format "#.#". And then I changed the text that would be shown in the last EditText to the new double variable with only one decimal (obviously changing it to String).
DecimalFormat df = new DecimalFormat("#.#");
double BMI_trimmed = Double.parseDouble(df.format(BMI));
final EditText BMIResult = (EditText)findViewById(R.id.BMIResult);
BMIResult.setText(Double.toString(BMI_trimmed));
Here I leave you all the code of the myButtonListenerMethod:
public void myButtonListenerMethod(){
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final EditText heighText = (EditText)findViewById(R.id.heightInput);
String heighStr = heighText.getText().toString();
double height = Double.parseDouble(heighStr);
final EditText weighText = (EditText)findViewById(R.id.weightInput);
String weighStr = weighText.getText().toString();
double weight = Double.parseDouble(weighStr);
double BMI = (weight)/(height*height);
DecimalFormat df = new DecimalFormat("#.#");
double BMI_trimmed = Double.parseDouble(df.format(BMI));
final EditText BMIResult = (EditText)findViewById(R.id.BMIResult);
BMIResult.setText(Double.toString(BMI_trimmed));
}
});
}
This app runs perfectly on the AVD, I've runned it in three already. But when I run it in a real device and click the button that starts the myButtonListenerMethod, it stops working suddenly and shuts down. The Terminal gives the following error message:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.bmicalculator, PID: 19058
java.lang.NumberFormatException: For input string: "24,2"
at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1306)
If anyone knows what the problem is, please tell me I'll try. Honestly I don't understand why it runs in the AVD but it doesn't properly in a real device. Any idea?
You already get the value rounded as you want and as a string from the formatter. Don't try to parse it, just display it.
BMIResult.setText(df.format(BMI));
The problem is probably your phone Locale. Some phones use . as a separator and some use , as separator. Try replacing all "," with "." before parsing from String to Double.
Also try using this answer:
https://stackoverflow.com/a/7559011/2249224
double BMI_trimmed = Double.parseDouble(df.format(BMI));
String yourResult = String.valueOf(BMI_trimmed);
Happy coding

Need an android button to execute with an intentionally blank EditText box

I have a simple screen with two EditText Boxes and 1 button. I want users to be able to enter various integers into the boxes and the program will perform different operations based on the specific number entered into the box. I'm trying to have them only enter one number at a time but the code wont seem to execute unless both boxes have something in them. And I'm having the if statements check for nulls on the respective boxes before executing to determine which piece of code to execute.
public void button(View view) {
double x, y;
EditText freq1 = findViewById(R.id.freq1);
EditText freq2 = findViewById(R.id.freq2);
TextView str1 = findViewById(R.id.freqanswer);
TextView str2 = findViewById(R.id.injVolt);
TextView error1 = findViewById(R.id.error1);
String strf1, strf2;
strf1 = freq1.getText().toString();
strf2 = freq2.getText().toString();
try {
f1 = Double.parseDouble(strf1);
f2 = Double.parseDouble(strf2);
if ((f1 >= 225) & (f1 <= 312) & (strf1.isEmpty())) {
x = f1 + 20.6;
y = x / 4;
str1.setText(String.format("%.3f", y));
}
}
catch (Exception e){
error1.setText("splat");
}
finally {
InputMethodManager input = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
input.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
I included only 1 formula for the sake of brevity, but I'm going to be putting about 6 if statements, checking for number ranges and nulls on this button and I just need it to run with one box being empty. I know the formula works by having play with various outputs, it just won't run with the strf1.isEmpty(). Something has to be in that second box for the formula to execute.
Would appreciate any help
I think you should check before assigning:
if(strf1.isEmpty()){strf1="0";} //if assuming zero does not change the formula's output
if(strf2.isEmpty()){strf2="0";}
f1 = Double.parseDouble(strf1);
f2 = Double.parseDouble(strf2);
this way you are assured of a default value.

Returning nothing instead of NaN

I'm creating a simple app that calculates BMI and I'm struggling with one small problem. I have 2 edit text fields, which are allowed to type numbers only. The point is when one of the text fields are empty the app is to generate a toast message and display nothing. I wrote an if statement to check if an edit text is empty and if not just to calculate further.
All would work fine, but I needed to put return statement and Android Studio suggested me writing "return 0;" so did I.
This is the code responsible for calculations:
/// parse input value from edittext field into double type
private double weight() {
EditText weightInput = (EditText) findViewById(R.id.weight_input);
String sWeightInput = weightInput.getEditableText().toString();
if (sWeightInput.matches("")){
Toast.makeText(this, R.string.noweight, Toast.LENGTH_SHORT).show();
} else {
String weight = sWeightInput;
double weightTyped = Double.parseDouble(weight);
return weightTyped;
}
return 0;
}
private double heigh() {
EditText heightInput = (EditText) findViewById(R.id.height_input);
String sHightInput = heightInput.getEditableText().toString();
if (sHightInput.matches("")){
Toast.makeText(this, R.string.noheight, Toast.LENGTH_SHORT).show();
} else {
String height = sHightInput;
double heightTyped = Double.parseDouble(height);
heightTyped = heightTyped / 100;
heightTyped = heightTyped * heightTyped;
return heightTyped;
}
return 0;
}
//make calculations and return the output value
public void makeCalculations(View view){
double result = weight() / heigh();
String message = String.valueOf(result);
TextView bmiSummaryTextView = (TextView) findViewById(R.id.bmi_calculation);
bmiSummaryTextView.setText(message);
}
This is the interface of the app.
To sum up, all I want to do is to display nothing instead of NaN (not a number).
Return a non-primitive Double rather than a double, and you will be able to use null as a value. Be sure to check for this value though, or you'll run into a NullPointerException.
Alternatively, you could look into using optionals, but since you're using Android you might need an external library for that (unless your minimum SDK version is high enough, then you can use Java 8's Optional).
The problem is probably if in your calculation weight() / height height is 0 it outputs NaN because it is infinity.
Also put your return 0; after Toast.makeText() in the condition. AS grumbles because you are not returning a value in the if branch.
if (sHightInput.matches("")){
Toast.makeText(this, R.string.noheight, Toast.LENGTH_SHORT).show();
return 0;
}
Maybe this will help you also to avoid dividing by zero.
public void makeCalculations(View view) {
String message = "Invalid input!";
if (weight() > 0 && height() > 0) {
double result = weight() / heigh();
String message = String.valueOf(result);
}
TextView bmiSummaryTextView = (TextView) findViewById(R.id.bmi_calculation);
bmiSummaryTextView.setText(message);
}

Result: NaN will not work?

Within the app I have different activity pages that call for the user to enter numerical data. I think of storing the data as below so I can use it on the final activity:
public void onClick(View v) {
String variable1 = input.getText().toString();
Double.parseDouble(variable1); //stores information put into variable
{ Intent myintent = (new Intent(step1.this,step2.class));
myintent.putExtra("variable1",variable1);
startActivity(myintent);
I do this same process for all the other activities up to the final one where I have:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);{
setContentView(R.layout.activity_iie);
Bundle extras = getIntent().getExtras(); //retrieves variables stored for formula
if(extras !=null){
double variable1 = extras.getDouble("VARIABLE1");
double vari2 = extras.getDouble("VARI2");
double vari3 = extras.getDouble("VARI3");
double finalvari = extras.getDouble("finalvari");
double solution= ((((vari2 - vari1) / (vari3) + finalvari)));
String lastString = "Result:" + solution; //prints out
TextView lastText = (TextView) findViewById(R.id.solution1);
lastText.setText(lastString);
}
I don't have any errors, but when I get to this final activity it prints out "Result:NaN". I'm trying to figure out why it is printing NaN; everything is set as a double.
What could cause this?
Update
#Melquiades
Yes I replaced the strings with the doubles as shown below:
'c.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
double variable1 = Double.parseDouble(input.getText().toString()); //stores information put into variable
{ Intent myintent = (new Intent(step1.this,step2.class));
myintent.putExtra("variabele1",variabele1);
startActivity(myintent);
'
Then in my final activity that is suppose to print the answer:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);{
setContentView(R.layout.activity_iie);
Bundle extras = getIntent().getExtras(); //retrieves variables stored formula
if (extras != null){
double variable1 = extras.getDouble("variable1");
double vari2 = extras.getDouble("vari2");
double vari3 = extras.getDouble("vari3");
double engagement = extras.getDouble("engagement1");
double solution= ((((vari2-variable1)/(vari3))+finalvari));
String lastString = "Result:" +solution; //prints out
TextView lastText= (TextView) findViewById(R.id.solution1);
lastText.setText(lastString);
Decided to post some more to potentially help like you suggested.
In the launching end, you just set one extra variable1.
In the receiving end, you attempt to four values from extras:
double variable1 = extras.getDouble("VARIABLE1");
double vari2 = extras.getDouble("VARI2");
double vari3 = extras.getDouble("VARI3");
double finalvari = extras.getDouble("finalvari");
getDouble() will return 0.0 if the key is not present.
Now, in here
double solution= ((((vari2-vari1)/(vari3)+finalvari)));
you divide by zero, which in floating point math causes the result to be Not a Number (NaN).
Key issue is that put String into intent:
String variable1 = input.getText().toString();
Double.parseDouble(variable1); //stores information put into variable
//...
myintent.putExtra("variable1",variable1); <- variable1 is a string,
and when you extract it later with getDouble() you will get, quote :
0.0 if no mapping of the desired type exists for the given key
So you should put double in your intent instead :
double variable1 = Double.parseDouble(input.getText().toString());
myintent.putExtra("variable1",variable1);
Please note, it is very important to use identical key String for mapping, when you extract your double, i.e. use "variable1", case-sensitive :
double extractedVar1 = extras.getDouble("variable1");
You could use extras.containsKey() to verify that your mapping exists.
All the advices are correct. but you are doing one cardinal mistake...
When you're sending your variables, you do:
myIntent.putExtra("variable1", variable1);
Then when your receive, you do:
double variable1 = extras.getDouble("VARIABLE1");
Your keys are NOT THE SAME. 'variable1' and 'VARIABLE1' are not equal, hence instead of the value of variable 1, you are probably getting 0 instead, and all your calculations are wrong.
For this reason, it's a good practice to use static finals for keys. Declare in your first activity:
public static final String KEY_VARIABLE1 = "variable1";
Use it when inserting in an intent:
myIntent.putExtra(KEY_VARIABLE1, variable1);
And when retrieving:
double variable = extras.getDouble(ActivityWhereThisKeyIsDeclared.KEY_VARIABLE1);
Do it for all your variables.

Another Android Activity or an iterative JAVA method?

I am new to Android application development and am trying to find a way to proceed through a series of screens that take in user input. I'm making a small math game where the user would answer basic two integer addition problems. So far the main menu is created. It has a New Game button which launches my GameActivity and it runs just fine for one math problem. However, after the user inputs their answer to the simple math problem, I would like to be able to continue on to another math problem once the user had answered the current problem and the method would return a correct/incorrect value. Initially I thought of doing something like a basic FOR loop from within the GameActivity :
for(int i = 0; i < 10; i++){ gameMethod(); }
gameMethod() is a JAVA method that simply generates 2 random numbers, adds them to get the correct answer and then prompts the user using an EditText field to type in their guess. It displays the random numbers and answer using TextView boxes created in an XML layout file.
Each call to the gameMethod would, at least I think, just re-input the randomized numbers into the TextView fields displayed on the screen each iteration. I really don't care what the previous numbers were so I figured I would just overwrite them. I wan't able to get the code to do that though. I put in a Log.d() statement or two and found that the FOR loop was in fact running through correctly 10 times, but it was not waiting for user input before firing off its next gameMethod().
In doing some looking around, I found the startActivityForResult() and wondered if this was a more appropriate way of approaching this. So in this way, I foresee having three Activities, the Main menu which calls the GameActivity which would then iterate through, say 10 times, each iteration calling yet another activity GameScreenActivity which would actually put the numbers on the screen, read in user input and then return 1 for a correct answer and 0 for an incorrect answer. So far in reading up on StarActivityForResult() I'm getting somewhat confused by the process and wondered if this was even a plausible path to be exploring.
Again, I'm very new at this Android programming and appreciate any and all help that I can get.
Thank you.
Sorry for not including the gameMethod() initially, I've added it below.
// Create and initialize arrays of integers
int[] a = {0,1,2,3,4,5,6,7,8,9,10};
int[] b = {0,1,2,3,4,5,6,7,8,9,10};
// Creates random number generator
Random randy = new Random();
// Generates two random values to add
int r1 = randy.nextInt(10);
int r2 = randy.nextInt(10);
// Calculates correct answer
int an = a[r1] + a[r2];
// Displays 1st number
TextView number1 = (TextView) findViewById(R.id.firstNumber);
number1.setText(Integer.toString(a[r1]));
// Displays 2nd number
TextView number2 = (TextView) findViewById(R.id.secondNumber);
number2.setText(Integer.toString(b[r2]));
// Displays correct answer
TextView answer1 = (TextView) findViewById(R.id.answerNumber);
//hide answer until user puts in theirs
answer1.setVisibility(View.INVISIBLE);
answer1.setText(Integer.toString(an));
//hide the answer place holder value
TextView uAnswerDisplay = (TextView) findViewById(R.id.userAnswerNumber);
uAnswerDisplay.setVisibility(View.INVISIBLE);
//Get the EditText field that the user will input their answer to
EditText inputText = (EditText) findViewById(R.id.userInput);
//set up a listener to run once the ENTER key is hit after their answer has been entered
inputText.setOnKeyListener(new EditText.OnKeyListener(){
public boolean onKey(View v, int keyCode, KeyEvent event){
//only go on the ENTER key when pressed DOWN
if((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)){
EditText innerInputText = (EditText) findViewById(R.id.userInput); //get the EditText box reference
TextView innerUAnswerDisplay = (TextView) findViewById(R.id.userAnswerNumber); //get the TextView box that the answer will go in
String inputString = innerInputText.getText().toString(); //capture the user's input
int uAnswer = Integer.parseInt(inputString); //parse user answer to an integer
int cAnswer = Integer.parseInt((((TextView) findViewById(R.id.answerNumber)).getText()).toString());
innerUAnswerDisplay.setText(Integer.toString(uAnswer)); //display the string after converting from integer
//change colors of text based on correctness
if (uAnswer == cAnswer){ innerUAnswerDisplay.setTextColor(Color.GREEN); } //green for correct
else { innerUAnswerDisplay.setTextColor(Color.RED); } //red for incorrect
innerUAnswerDisplay.setVisibility(View.VISIBLE); //make the user input answer visible
TextView innerAnswer1 = (TextView) findViewById(R.id.answerNumber);
innerAnswer1.setVisibility(View.VISIBLE); //hide answer until user puts in theirs
} //end of if
return false; //return false
} //end of onKey
}); //end of setOnKeyListener
Sorry for all the edits, I couldn't get the edits to include the code and post correctly so I broke it up into chunks and added a little at a time.
From what you say, I'd consider two ways of letting the user answer questions:
have an onclick listener on the input EditText that triggers a new loop;
have a dialog activity that gets started in the beginning of the loop, which prompts the user for a new answer, your game activity would receive the answer via its onActivityResult.

Categories