UPDATE - solution below
I'm new to java (and programming as a whole) and could really use some help.
I'm working on a fragment that includes a timer and counter. The user punches a number into an edit text and hits a "set" button to set the timer to that number in minutes. There's also a frequency counter that increases by 1 each time it's clicked. When the timer reaches zero, I want a "rate" text view to show the result of dividing the number of times the button was clicked by the number of minutes; rate = frequency/minute. For example: If minutes = 5 and frequency = 7, I want the rate text view to display "0.71".
So far, I've gotten the timer and counter to work, but I can't get the rate calculation to work. I keep getting "infinity," which from what I've read means I'm dividing by an integer. What I can't figure out is which number is still an integer. I'm also uncertain that the layout of my code is correct (maybe I'm declaring something where I shouldn't?)
Any help would be greatly appreciated. Thanks in advance!
I've tried using a try/catch statement to avoid dividing by 0. In XML, I've tried setting the input type to "numberDecimal" I've tried converting the edit text to an integer and text view to a string before converting to doubles I've tried converting the edit text and counter directly as doubles. I've searched stackoverflow, Quora, and YouTube to make sure I'm calculating correctly.
Solution
@Override
public void onFinish() {
mTimerRunning = false;
button_start_pause.setText("Start");
button_start_pause.setVisibility(android.view.View.INVISIBLE);
button_reset.setVisibility(android.view.View.VISIBLE);
text_view_rate.setVisibility(android.view.View.VISIBLE);
calculaterate();
}
}.start();
mTimerRunning = true;
button_start_pause.setText("Pause");
}
public void pauseTimer() {
countDownTimer.cancel();
mTimerRunning = false;
button_start_pause.setText("Start");
updateCountDownText();
}
public void resetTimer() {
if (mTimerRunning) {
countDownTimer.cancel();
mTimeLeftInMillis = (mStartTimeInMillis + 1000);
updateWatchInterface();
startTimer();
} else {
mTimeLeftInMillis = (mStartTimeInMillis);
updateCountDownText();
updateWatchInterface();
button_reset.setVisibility(android.view.View.VISIBLE);
button_start_pause.setVisibility(android.view.View.VISIBLE);
}
}
public void calculaterate() {
double numerator = Double.parseDouble(text_view_frequency.getText().toString());
double denominator = (mStartTimeInMillis/1000)/60;
double rate = (numerator)/(denominator);
DecimalFormat df = new DecimalFormat("#.00");
String ratecalc = df.format(rate);
text_view_rate.setText(ratecalc);
}
Fragment and component IDs
public class fragmentrate extends Fragment {
private EditText edit_text_input;
private TextView text_view_countdown;
private TextView text_view_frequency;
private TextView text_view_rate;
private TextView rate_equals;
private Button button_start_pause;
private Button button_reset;
private Button button_set;
private Button button_frequency;
private Button button_reset_frequency;
private CountDownTimer countDownTimer;
private boolean mTimerRunning;
private long mStartTimeInMillis;
private long mTimeLeftInMillis = mStartTimeInMillis;
private long mEndTime;
private int mCounter;
private double denominator;
View View;
public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @NonNull Bundle savedInstanceState) {
View = inflater.inflate(R.layout.rate_fragment, container, false);
text_view_countdown = View.findViewById(R.id.text_view_countdown);
button_start_pause = View.findViewById(R.id.button_start_pause);
button_reset = View.findViewById(R.id.button_reset);
button_frequency = View.findViewById(R.id.button_frequency);
button_reset_frequency = View.findViewById(R.id.button_reset_frequency);
edit_text_input = View.findViewById(R.id.edit_text_input);
button_set = View.findViewById(R.id.button_set);
text_view_frequency = View.findViewById(R.id.text_view_frequency);
text_view_rate = View.findViewById(R.id.text_view_rate);
rate_equals = View.findViewById(R.id.rate_equals);
Frequency counter
button_frequency.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(android.view.View view) {
mCounter ++;
text_view_frequency.setText(Integer.toString(mCounter));
}
});
button_reset_frequency.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(android.view.View view) {
mCounter = 0;
text_view_frequency.setText(Integer.toString(mCounter));
}
});
Timer and rate calculation
button_set.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(android.view.View view) {
String input = edit_text_input.getText().toString();
if (input.length() == 0) {
Toast.makeText(getActivity(), "Please enter a number", Toast.LENGTH_SHORT).show();
return;
}
long millisInput = Long.parseLong(input) * 60000;
if (millisInput == 0) {
Toast.makeText(getActivity(), "Please enter a positive number", Toast.LENGTH_SHORT).show();
return;
}
setTime(millisInput);
edit_text_input.setText("");
}
});
button_start_pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(android.view.View view) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
button_reset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(android.view.View view) {
if(mTimerRunning) {
resetTimer();
} else{
resetTimer();
}
}
});
return View;
}
private void setTime(long milliseconds) {
mStartTimeInMillis = milliseconds;
resetTimer();
}
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
countDownTimer = new CountDownTimer(mTimeLeftInMillis, 100) {
@Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
@Override
public void onFinish() {
mTimerRunning = false;
button_start_pause.setText("Start");
button_start_pause.setVisibility(android.view.View.INVISIBLE);
button_reset.setVisibility(android.view.View.VISIBLE);
try {
double denominator = Integer.parseInt(edit_text_input.getText().toString());
double rate = ((double)mCounter/denominator);
text_view_rate.setText(Double.toString(rate));
}
catch (NumberFormatException e)
{
}
}
}.start();
mTimerRunning = true;
button_start_pause.setText("Pause");
}
private void pauseTimer() {
countDownTimer.cancel();
mTimerRunning = false;
updateCountDownText();
button_start_pause.setText("Start");
}
private void resetTimer() {
if (mTimerRunning) {
countDownTimer.cancel();
mTimeLeftInMillis = (mStartTimeInMillis + 1000);
updateWatchInterface();
startTimer();
} else {
}
mTimeLeftInMillis = (mStartTimeInMillis);
updateCountDownText();
updateWatchInterface();
button_reset.setVisibility(android.view.View.VISIBLE);
button_start_pause.setVisibility(android.view.View.VISIBLE);
}
private void updateCountDownText() {
int minutes = (int) (mTimeLeftInMillis/1000)/60;
int seconds = (int) (mTimeLeftInMillis/1000)%60;
String timeLeftFormatted = String.format(Locale.getDefault(),
timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds));
text_view_countdown.setText(timeLeftFormatted);
}
I expect the output of 5/7 to be 0.71, but the actual output is "Infinity"