How to use value from Seekbar value? - java

The code works fine but the seekbar value is not fetched in my code. The error shown is "Cannot resolve symbol progress" even after making it public. Someone throw light on this possibly with short explanation. I have stored the SeekBar value in progress and tried to use it in calculation further.
sb = (SeekBar)findViewById(R.id.set_years);
yrs = (TextView)findViewById(R.id.years);
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public int progress;
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
progress = i;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
yrs.setText(progress+" year(s)");
}
});
addButtonClickListener();
}
private void addButtonClickListener() {
submit = (Button)findViewById(R.id.submit);
submit.setOnClickListener(this);
}
#Override
public void onClick(View view) {
float loanAmtValue = 0;
float roiValue = 0;
double answer;
loanAmt = (EditText)findViewById(R.id.amt);
loanAmtValue = Float.parseFloat(loanAmt.getText().toString());
roi = (EditText)findViewById(R.id.roi);
roiValue = Float.parseFloat(roi.getText().toString());
if (loanAmtValue != 0 || roiValue != 0){
answer = (loanAmtValue * roiValue * progress) / 100;
siResult = (TextView) findViewById(R.id.result);
siResult.setText("Calculated Simple Interest for Amount Rs" + loanAmtValue + " and ROI " + roiValue + "% is = " + Double.toString(answer));
loanAmt.setText("0");
roi.setText("0");
}
else
{
siResult.setText("Please provide valid details");
}

First of all - your progress variable is member of SeekBar.OnSeekBarChangeListener anonymous inner class. You cannot access it directly without having reference to instance of this listener.
Second of all - you do not need to store the progress by yourself. Use sb.getProgress();.

Check your imports for the error "Cannot resolve symbol progress".
and check too, if you define the max for seekbar.

Related

How to calculate ProgressBar percentage for daily drink water

I made an app about android water drinking monitor. But it does the wrong calculation as a percentage. What do you think I might have done wrong.
(When the progress bar is 100 at 100, the daily water calculation is wrong)
waterml = sharedPreferences.getInt(WATER_ML, 0);
waterdata = sharedPreferences.getInt(WATER_DATA, 0);
int dailywater = 2838; // example
ml100.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//scale 100 ml
int percent = 100 * 100 / dailywater;
ProgressBarAnimation anim = new ProgressBarAnimation(circlebar, waterdata, (waterdata + percent));
anim.setDuration(300);
circlebar.startAnimation(anim);
dailywater.setText((waterml + 100) + " / " + dailywater + " ml");
editor = sharedPreferences.edit();
editor.putInt(WATER_DATA, (waterdata + percent));
editor.putInt(WATER_ML, (waterml + 100));
editor.apply();
}
});
////
public static class ProgressBarAnimation extends Animation {
private CircleProgressBar progressBar;
private float from;
private float to;
ProgressBarAnimation(CircleProgressBar progressBar, float from, float to) {
super();
this.progressBar = progressBar;
this.from = from;
this.to = to;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
float value = from + (to - from) * interpolatedTime;
progressBar.setProgress((int) value);
}
}
It seems to me like your code, namely editor.apply(); is working as follows:
you are trying to save the progress and it occurs that sometimes it is called multiple times in a row. According to documentation if you are sending several apply() or commit() commands only the last one will be executed. Therefore, some clicks might not be processed.
I suggest you simply changing your variable for progress and saving it later:
waterml = sharedPreferences.getInt(WATER_ML, 0);
waterdata = sharedPreferences.getInt(WATER_DATA, 0);
int dailywater = 2838; // example
ml100.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//scale 100 ml
int percent = 100 * 100 / dailywater;
ProgressBarAnimation anim = new ProgressBarAnimation(circlebar, waterdata, (waterdata + percent));
anim.setDuration(300);
circlebar.startAnimation(anim);
dailywater.setText((waterml + 100) + " / " + dailywater + " ml");
waterdata += percent;
waterml += 100;
}
});
and then in your onPause() function you simply save them:
public void onPause() {
editor = sharedPreferences.edit();
editor.putInt(WATER_DATA, waterdata);
editor.putInt(WATER_ML, waterml);
editor.apply();
}
If you want your percent not to be rounded, you could change putInt to putFloat and getInt to getFloat

Timer and TimerTask with scheduleAtFixedRate causes CalledFromWrongThreadException crash when updating TextView

I'm new to Android programming. Right now, I want to update a TextView value in an Activity at a specified interval.
Car class:
public class Car {
public int Speed;
public int RPM;
public int Distance;
public int Fuel;
public Car(int Speed, int RPM, int Distance, int Fuel) {
System.out.println(
"Inisialisasi Baru"+
"\nSpeed: "+ Speed +
"\nRPM: "+ RPM +
"\nDistance: "+ Distance +
"\nFuel: "+ Fuel
);
this.Speed = Speed;
this.RPM = RPM;
this.Distance = Distance;
this.Fuel = Fuel;
}
public int getSpeed() {
return Speed;
}
public int getRPM() {
return RPM;
}
public int getDistance() {
return Distance;
}
public int getFuel() {
return Fuel;
}
}
Activity java:
TextView carSpeed, carRPM, carDistance, carFuel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mock);
carSpeed = (TextView) findViewById(R.id.carSpeed);
carRPM = (TextView) findViewById(R.id.carRPM);
carDistance = (TextView) findViewById(R.id.carDistance);
carFuel = (TextView) findViewById(R.id.carFuel);
new Timer().scheduleAtFixedRate(new TimerTask(){
Car car = new Car(20, 20, 20, 5);
#Override
public void run(){
int maxSpeed = car.Speed + 5;
int minSpeed = car.Speed - 4;
int maxRPM = car.RPM + 5;
int minRPM = car.RPM - 4;
car.Speed = new Random().nextInt((maxSpeed - minSpeed) + 1) + minSpeed;
car.RPM = new Random().nextInt((maxRPM - minRPM) + 1) + minRPM;
car.Distance += 1;
car.Fuel -= 1;
if (car.Fuel <= 0) {
car.Fuel += 20;
}
if (car.Speed <= 0) {
car.Speed = 20;
} else if (car.Speed >= 150) {
car.Speed -= 50;
}
carSpeed.setText(Integer.toString(car.getSpeed()) + " km/h");
carRPM.setText(Integer.toString(car.getRPM()) + " rpm");
carDistance.setText(Integer.toString(car.getDistance()) + " km");
carFuel.setText(Integer.toString(car.getFuel()) + " l");
}
},0,5000);
}
I think the problem happens because I'm trying to setText inside new Timer() and this cause application close. Thank you.
Yes your intuition is correct. The problem happens because the views are being updated from the timer.
The error will be similar to this:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the
original thread that created a view hierarchy can touch its views.
In Android, views can only be updated from the "UI thread" also commonly known as the "Main Thread".
The problem here is that the Runnable's run() method is being executed in a separate thread.
The updates can be done on the main thread from an Activity like this:
...
runOnUiThread(new Runnable() {
#Override
public void run() {
// Do all your view updates in here
textView.setText("string");
}
});
....
I cannot see the context of your code, but if it is a fragment:
getActivity().runOnUiThread(...);
There are also other methods for switching to the main thread. You may want to investigate AsyncTask and Handlers as well.

Input Validation not working android studio

For some reason my input Validation is not working. Every time I put calculate it crashes "app" when it should have an error saying that I need to input height/weight. When I do input the numbers it does calculate. Thanks for the help :). I'm new to android studio .
here is my calculation java file
public class BmiFrag extends Fragment implements View.OnClickListener {
Button BmiButton;
private double weight1=0;
private double height1=0;
public static EditText heightIn;
public static EditText weightIn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.fragment_bmi, container, false);
BmiButton = (Button) myView.findViewById(R.id.CalculateBmi);
BmiButton.setOnClickListener(this);
return myView;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.CalculateBmi:
weightIn = (EditText)
getActivity().findViewById(R.id.ETtweight);
heightIn = (EditText) getActivity().findViewById(R.id.ETHeight);
final TextView tv4 = (TextView)
getActivity().findViewById(R.id.TFDisplayBmi);
String str1 = weightIn.getText().toString();
String str2 = heightIn.getText().toString();
float weight = Float.parseFloat(str1);
float height = Float.parseFloat(str2) ;
float bmiValue = calculateBMI(weight, height);
String bmiInterpretation = interpretBMI(bmiValue);
tv4.setText(String.valueOf(bmiValue + "-" + bmiInterpretation));
if (TextUtils.isEmpty(str1)) {
weightIn.setError("Please enter your weight");
weightIn.requestFocus();
return;
}
else if (TextUtils.isEmpty(str2)) {
heightIn.setError("Please enter your height");
heightIn.requestFocus();
return;
}
break;
}
}
private float calculateBMI(float weight, float height) {
float bmi= (float) (weight/ (height*height)*4.88);
float total= Math.round(bmi);
return total;
}
private String interpretBMI(float bmiValue) {
if (bmiValue < 16) {
return "Severely underweight";
} else if (bmiValue < 18.5) {
return "Underweight";
} else if (bmiValue < 25) {
return "Normal";
} else if (bmiValue < 30) {
return "Overweight";
} else {
return "Obese";
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onDestroy() {
}
#Override
public void onDetach() {
super.onDetach();
}
}
Try to change the code like the following,
if (TextUtils.isEmpty(str1)) {
weightIn.setError("Please enter your weight");
weightIn.requestFocus();
return;
}
else if (TextUtils.isEmpty(str2)) {
heightIn.setError("Please enter your height");
heightIn.requestFocus();
return;
}else{
float weight = Float.parseFloat(str1);
float height = Float.parseFloat(str2) ;
float bmiValue = calculateBMI(weight, height);
String bmiInterpretation = interpretBMI(bmiValue);
tv4.setText(String.valueOf(bmiValue + "-" + bmiInterpretation));
}
if (TextUtils.isEmpty(str1)) {
weightIn.setError("Please enter your weight");
weightIn.requestFocus();
return;
}
if (TextUtils.isEmpty(str2)) {
heightIn.setError("Please enter your height");
heightIn.requestFocus();
return;
}
firstly, sort your indentation and variable names out. Never name a variable str1, str2: always meaningful names. Indentation should always be consistent. This will help out but fixing in the future for readability and speed.
You're doing input validation after you actually input and assign things through
calculateBMI() method
That part of your code reads: Lets take text from text fields, interpret the BMI and then see if the textfields are empty

How to make SeekBar value go up by 5s? And how to pass user selected seekbar value to a method?

I have two problems, first, I want my seekbar to display values as follows: 5, 10, 15, 20...30. I have set max=30 and progress=5, but that doesn't do. Second, I need the value selected by the user via seekbar to be passed into calculatePayments() method after the user clicks the Calculate button. Anyone please help me out? I would appreciate it! Thanks!
public class AKMainActivity extends Activity {
private EditText loanAmount, interestRate, loanYears;
private TextView monthlyPaymentsResult, totalPaymentsResult, seek_barTV;
private static SeekBar seek_bar;
private static TextView textview_seek;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_akmain);
seekbarr();
loanAmount = (EditText)findViewById(R.id.loanET);
interestRate = (EditText) findViewById(R.id.intrateET);
monthlyPaymentsResult = (TextView) findViewById(R.id.monthlyResultTV);
totalPaymentsResult = (TextView) findViewById(R.id.totalResultsTV);
}
public void seekbarr(){
seek_bar = (SeekBar) findViewById(R.id.seekBar1);
textview_seek = (TextView) findViewById(R.id.seekbarTV);
textview_seek.setText(seek_bar.getProgress() + "Years");
seek_bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int years_number = 5;
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
textview_seek.setText(years_number + " Years");
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
years_number = progress;
textview_seek.setText(years_number + " Years");
progress = seek_bar.getProgress();
}
});
}
public void calculatePayments(View clickedButton) {
double loan = Integer.parseInt(loanAmount.getText().toString());
double interest = (Integer.parseInt(interestRate.getText().toString()));
double years = seek_bar.getProgress();
double r = years / 1200;
double r1 = Math.pow(r + 1, years);
double monthlyPayment = (double) ((r + (r / (r1 - 1))) * loan);
double totalPayment = monthlyPayment * years;
monthlyPaymentsResult.setText(new DecimalFormat("##.##").format(monthlyPayment));
totalPaymentsResult.setText(new DecimalFormat("##.##").format(totalPayment));
}
}
To set the progress increment you can do:
seekBar.incrementProgressBy(5);
You also need to get a reference to your button, the same way you did for you other views (TextView, SeekBar,etc.) and in your Button's onClick listener you can call the calculatePayments method, with the current seekbar value as an argument. To get the current value of the seekbar use:
seekBar.getProgress();

Getting value from 3 Textviews and converting to int for Countdown Timer

Currently I have three textviews which I am using for the countdown timer in my android app in HH:MM:SS. (hours, minutes and seconds). I am allowing the user to set the textviews to a specific number for the time. I am then trying to get the value from the textviews by converting to int and then using the integer values as the seconds for the countdown timer. But the problem is that there is no values for the ints, and therefore the timer cannot start.
As the user drags around the scrubber he can change the textview value for hours, minutes, or seconds:
Here is the code for that below in my onCreate method:
#Override
public void onProgressChanged(SeekArc seekArc, int progress,
boolean fromUser) {
int progress_count = 0;
for (int i=0;i<24;i=i+1)
{
if (progress ==120) {
mSeekArcProgress.setText("24");
}
else if (progress == progress_count)
{
mSeekArcProgress.setText(String.valueOf(String.format("%02d",i)));
}
progress_count = progress_count + 5;
}
}
});
} else if (v.getId() == R.id.minutetext) {
//corresponding button logic should below here
mSeekArc.setOnSeekArcChangeListener(new SeekArc.OnSeekArcChangeListener() {
#Override
public void onStopTrackingTouch(SeekArc seekArc) {
}
#Override
public void onStartTrackingTouch(SeekArc seekArc) {
}
//This sets the actual string for the minutes
#Override
public void onProgressChanged(SeekArc seekArc, int progress,
boolean fromUser) {
int progress_count = 0;
for (int i=0;i<120;i++)
{
if (progress ==120) {
mSeekArcMinuteProgress.setText("00");
}
else if (progress == progress_count)
{
mSeekArcMinuteProgress.setText(String.valueOf(String.format("%02d",i)));
}
progress_count = progress_count + 2;
}
}
});
} else if (v.getId() == R.id.secondtext) {
//corresponding button logic should below here
mSeekArc.setOnSeekArcChangeListener(new SeekArc.OnSeekArcChangeListener() {
#Override
public void onStopTrackingTouch(SeekArc seekArc) {
}
#Override
public void onStartTrackingTouch(SeekArc seekArc) {
}
//This sets the actual string for the seconds
#Override
public void onProgressChanged(SeekArc seekArc, int progress,
boolean fromUser) {
// so ur setting it to HALF of what "progress" is = to
int progress_count = 0;
for (int i=0;i<60;i++)
{
if (progress ==120) {
mSeekArcSecondProgress.setText("00");
}
else if (progress == progress_count)
{
mSeekArcSecondProgress.setText(String.valueOf(String.format("%02d",i)));
}
progress_count = progress_count + 2;
}
}
});
}
The TextView ID's are referenced in the following code which is in my setActionListener method for the countdown timer:
private void setActionListeners() {
// IT IS RIGHT BELOW CHECK IT OUT.
number_text = (TextView) findViewById(R.id.hour_progress_number);
minute_text = (TextView) findViewById(R.id.minute_progress_number);
second_text = (TextView) findViewById(R.id.second_progress_number);
hourint = Integer.valueOf(number_text.getText().toString());
minuteint = Integer.valueOf(minute_text.getText().toString());
secondint = Integer.valueOf(second_text.getText().toString());
totalTimeCountInMilliseconds = ((hourint*60*60) +(minuteint*60) + (secondint)) * 1000; // time count for 3 minutes = 180 seconds
timeBlinkInMilliseconds = totalTimeCountInMilliseconds/1000;
start_timer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// textViewShowTime.setTextAppearance(getApplicationContext(), R.style.normalText);
countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
// 500 means, onTick function will be called at every 500 milliseconds
#Override
public void onTick(long leftTimeInMilliseconds) {
long seconds = leftTimeInMilliseconds / 1000;
mSeekArc.setVisibility(View.INVISIBLE);
if ( leftTimeInMilliseconds < timeBlinkInMilliseconds ) {
// textViewShowTime.setTextAppearance(getApplicationContext(), R.style.blinkText);
// change the style of the textview .. giving a red alert style
if ( blink ) {
number_text.setVisibility(View.VISIBLE);
minute_text.setVisibility(View.VISIBLE);
second_text.setVisibility(View.VISIBLE);
// if blink is true, textview will be visible
} else {
number_text.setVisibility(View.INVISIBLE);
minute_text.setVisibility(View.INVISIBLE);
second_text.setVisibility(View.INVISIBLE);
}
blink = !blink; // toggle the value of blink
}
second_text.setText(String.format("%02d", seconds % 60));
minute_text.setText(String.format("%02d", seconds / 60));
number_text.setText(String.format("%02d", seconds / 3600)); // format the textview to show the easily readable format
}
#Override
public void onFinish() {
// this function will be called when the timecount is finished
//textViewShowTime.setText("Time up!");
number_text.setVisibility(View.VISIBLE);
minute_text.setVisibility(View.VISIBLE);
second_text.setVisibility(View.VISIBLE);
mSeekArc.setVisibility(View.VISIBLE);
}
}.start();
}
});
}
The timer works went I put an explicit integer value for totalTimeCountInMilliseconds; however, when I use hourint, minuteint, and secondint the value is probably zero because the timer doesn't start and that seems like that is the only valid reason.
I am not sure what to do the fix this so I can get integer values and make the timer work.
EDIT: Pastebin for full code link: http://pastebin.com/1wcXHdvX
You can use
Log.i("YourActivity","Seconds: " + secondsint);
to check, what are the values you get from textviews.
Dont forget to add imports. You can use Ctrl+Shift+O and select the Android Logcat import.
EDIT1:
I looked you code and you are calling setActionListeners() in your OnCreateMethod(). That does not make sense! setActionListeners() get the values from the TextViews from the user. But User cant enter values when system initializes the activity. So, call your setActionListeners() here:
start_timer.setOnClickListener(new View.OnClickListener() {
setActionListeners();
#Override
public void onClick(View view) {
...
}
...
}
And move the start_timer.setOnClickListener(new View.OnClickListener(){...})
to onCreateMethod()

Categories