I have several SeekBars in an Android app that do practically the same thing (set bass, treble, volume). To save typing out new local classes for OnSeekBarChangeListener per SeekBar, I tried to make a single class that in its onStopTrackingTouch would determine which widget was calling it, and do the proper action.
public class mySeekBar implements SeekBar.OnSeekBarChangeListener {
int progressChanged = 0;
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser){
progressChanged = progress;
}
public void onStartTrackingTouch(SeekBar seekBar) {}
public void onStopTrackingTouch(SeekBar seekBar) {
// i want a case statement here switched on the widget ID/name, so
// i can set the appropriate string s (bass, treble, volume)
String s = "set_treble " + progressChanged;
client.sendMessage(s);
}
}
How do I figure out which widget is calling the onStopTrackingTouch? Or is there a cleaner or better way of doing this?
100 % you can determine like this;
public void onStopTrackingTouch(SeekBar seekBar) {
// i want a case statement here switched on the widget ID/name, so
// i can set the appropriate string s (bass, treble, volume)
String s = "set_treble " + progressChanged;
client.sendMessage(s);
switch (seekBar.getId()) {
case R.id.seekVolume:
break;
case R.id.bass:
break;
case R.id.trouble:
break;
default:
break;
}
}
Related
so i have been trying to make this BMI calculator in android studio, where your BMI will instantly get calculated when you drag Progress-bar to any value .
To execute this, what i did was-
inside the the Bundle class,
i directly declared 2 variable and assigned one of them to get the data from the Height progress bar and another to get the data from weight progress bar.
and then i wrote the typical code for the calculation and the text setting.
And it did not work
For myself being a very new to this, i really cant find my mistake here.
so as a result what i got was- a still BMI which was the result for the initial value of the progress-bar that i have set for the height and weight.
i am getting a feeling that i made a very silly mistake somewhere that i still can not notice.
Would you be kind enough to point that out?
the Java code that i have used is below, please check it-
The code for the BMI is at the end. I feel the problem is lying there.
here is the screenshot of the app-
screenshot2
screenshot1
here is my code--
public class MainActivity extends AppCompatActivity {
TextView mheighttext,mweighttext2,mbmitext,mfunnymsg;
SeekBar mbar1, mbar2;
RelativeLayout mweightlayout, mlayout3;
ImageView mgincbtn1,mgincbtn2,mgdecbtn1,mgdecbtn2;
String mbmi, bmitext;
int wt= 45;
String wtwt="45";
int ht= 158;
String htht="158";
float rslt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
mheighttext=findViewById(R.id.heighttext);
mweighttext2=findViewById(R.id.weighttext2);
mbar1= findViewById(R.id.bar1);
mbar2=findViewById(R.id.bar2);
mgincbtn1=findViewById(R.id.gincbtn1);
mgincbtn2=findViewById(R.id.gincbtn2);
mgdecbtn1=findViewById(R.id.gdecbtn1);
mgdecbtn2=findViewById(R.id.gdecbtn2);
mbmitext=findViewById(R.id.bmitext1);
mfunnymsg=findViewById(R.id.funnymsg);
mbar1.setMax(246);
mbar1.setProgress(160);
mbar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
ht=progress;
htht=String.valueOf(ht);
mheighttext.setText(htht);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mbar2.setMax(244);
mbar2.setProgress(50);
mbar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
wt=progress;
wtwt=String.valueOf(wt);
mweighttext2.setText(wtwt);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mgincbtn1.setOnClickListener(v -> {
ht=ht+1;
if (ht>=0 && ht<247) {
mbar1.setProgress(ht);
htht = String.valueOf(ht);
mheighttext.setText(htht);
}
});
mgdecbtn1.setOnClickListener(v -> {
ht=ht-1;
if (ht>=0 && ht<247) {
mbar1.setProgress(ht);
htht = String.valueOf(ht);
mheighttext.setText(htht);
}
});
mgincbtn2.setOnClickListener(view -> {
wt=wt+1;
if (wt>=0 && wt<244) {
mbar2.setProgress(wt);
wtwt = String.valueOf(wt);
mweighttext2.setText(wtwt);
}
});
mgdecbtn2.setOnClickListener(v -> {
wt=wt-1;
if (wt>=0 && wt<244) {
mbar2.setProgress(wt);
wtwt = String.valueOf(wt);
mweighttext2.setText(wtwt);
}
});
int htt = mbar1.getProgress();
int wtt = mbar2.getProgress();
float httt=htt/100;
rslt= wtt/(httt*httt);
mbmi=Float.toString(rslt);
mbmitext.setText(mbmi);
}
}
}
You would want to put the snippet of code that calculates the BMI (perhaps the last 4 lines of code) in both onProgressChanged() to instantly calculate BMI as height/weight gets changed. Since you're setting global variables for both height and weight, you'll get current values for each of them.
You can also make a function for calculating the BMI like this:
private float calculateBMI(int height, int weight) {
float ht = height / 100;
float result = weight / (ht * ht);
return result;
}
and have this function call in both onProgressChanged() like so (for the weight for example):
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
wt = progress;
mweighttext2.setText(String.valueOf(getBMI(ht, progress)));
}
Move this your code...
int htt = mbar1.getProgress();
int wtt = mbar2.getProgress();
float httt=htt/100;
rslt= wtt/(httt*httt);
mbmi=Float.toString(rslt);
mbmitext.setText(mbmi);
to a method say
public void computeBMI(){
int htt = mbar1.getProgress();
int wtt = mbar2.getProgress();
float httt=htt/100;
rslt= wtt/(httt*httt);
mbmi=Float.toString(rslt);
mbmitext.setText(mbmi);
}
Then add a button in your UI say mCompute. In your oncreate method you can then implement that buttons onClickListener to call computeBMI() above.
That is:
yourButton.setOnclickListener((v)->{
computeBMI();
});
I'm getting java.lang.IllegalStateException in my Android Music Player Application every time when I closes the Activity
mCurrentPosition = mediaPlayer.getCurrentPosition()/1000; // In milliseconds
I've tried nearly all the codes available and even all at java.lang.illegalStateException randomly occurs when getting mediaPlayer.getCurrentPosition also
Here's my Java code where I'm using it:
protected void initializeSeekBar(){
mSeekBar.setMax(mediaPlayer.getDuration()/1000);
mRunnable = new Runnable() {
#Override
public void run() {
int mCurrentPosition;
if(mediaPlayer!=null && mediaPlayer.isPlaying()){
mCurrentPosition = mediaPlayer.getCurrentPosition()/1000; // In milliseconds
}
else {
mCurrentPosition = 0;
}
if (mSeekBar != null) {
mSeekBar.setProgress(mCurrentPosition);
getAudioStats();
}
handler.postDelayed(mRunnable,1000);
}
};
handler.postDelayed(mRunnable,1000);
}
Please Help me out of this. Thanks in Advance
Edit 1
Also, my Seekbar goes to start when the music pauses and on play, it continues from where it was before pausing
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
getAudioStats();
initializeSeekBar();
if(mediaPlayer != null && fromUser) {
mediaPlayer.seekTo(progress * 1000);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
protected void getAudioStats(){
long duration = mediaPlayer.getDuration()/1000; // In milliseconds
long due = (mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition())/1000;
long pass = duration - due;
String test = DateUtils.formatElapsedTime(pass);
String test1 = DateUtils.formatElapsedTime(due);
current_time.setText("" + test);
//mDuration.setText("" + duration + " seconds");
total_time.setText("" + test1);
}
You need to remove your runnable from the handler queue when the activity closes (or, better yet, when it pauses). Try putting this in your activity's onPause() method:
handler.removeCallbacks(mRunnable);
For additional robustness, inside the runnable itself, you should only re-queue the runnable if the activity is still active. So instead of this:
handler.postDelayed(mRunnable,1000);
you should do this (assuming this code is in the activity class):
if (!isDestroyed()) {
handler.postDelayed(mRunnable,1000);
}
Also make sure you are stopping the media player before the activity is destroyed.
P.S. If you call initializeSeekBar() multiple times, you will be reassigning mRunnable and leaving the old one in the handler queue where it can cause trouble later. To fix this, you should add this at the start of initializeSeekBar():
protected void initializeSeekBar(){
if (mRunnable != null) {
handler.removeCallbacks(mRunnable);
}
// ... the rest of the method that you currently have
I am trying to implement some button events without any reference to the XML-File and with databinding instead of FindByID. Is this possible? I am having the problem that, within the OnKeyListener, the bound InputBox from which I try to get the typed text seems inaccessible (this.binding shows in red color where I put it bold). Is this a wrong approach or am I making a mistake? I'd like to avoid all that FindByID-Lines.
this.binding =
DataBindingUtil.setContentView(this, R.layout.content_main);
this.binding.EditNumber.setText("553");
this.binding.EditNumber.setOnKeyListener(new OnKeyListener()
{
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
Cat supertest = Manager.CreateMainCat(this.**binding**.EditNumber.toString());
this.**binding**.DisplayCurrentBudget.setText(supertest.getsName());
return true;
default:
break;
}
}
return false;
}
});
Thank you very much
Strangely, it works when I simply put the binding in another method:
(...)
this.binding.Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
xxx();
}
});
}
public void xxx()
{
Cat supertest = Manager.CreateMainCat(this.binding.EditNumber.getText().toString());
this.binding.DisplayCurrentBudget.setText(supertest.getsName());
}
But this doesn't:
this.binding.Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cat supertest = Manager.CreateMainCat(this.binding.EditNumber.getText().toString());
this.binding.DisplayCurrentBudget.setText(supertest.getsName());
}
The propblem is solved easily, but I'd be very interested to know what's going if someone has the answer :)
I'm implementing a seekbar that allows users to set a price.
I want the seekbar to start out with a max of 100, then if the user moves the seekbar all the way up to 100, the max goes up to 250 and if the user moves the seekbar all the way up to 250 it goes up to 500, finally stopping at 500+ if the user moves the seekbar all the way up to 500.
The code that I've written works, for the most part. The problem is that when the user moves the seekbar up to the max, since the user is holding their finger there, android thinks that it's constantly at the max so it just instantly increases to 500+, so I need to find a way to disable touch after increasing the max until the user lifts their finger.
So...I want to break the user's touch from the seekbar so that it waits until the next NEW touch event so that this won't happen. If anyone knows a way to do this, please let me know asap!! thanks!
What I've already tried is disable and reanabling the seekbar when it reaches the max, in hopes of breaking the touch, but this doesn't work.
The code I have is below:
private class PriceChangeListener implements SeekBar.OnSeekBarChangeListener{
private TextView priceView = (TextView) findViewById(R.id.input_price_label);
private TextView maxPriceView = (TextView) findViewById(R.id.input_price_max_label);
private boolean increaseMax;
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
String textToSet = "About how much will it cost? $" + String.valueOf(progress);
if(progress < 500)
priceView.setText(textToSet);
else
priceView.setText(textToSet + "+");
if(progress == seekBar.getMax() && increaseMax) {
seekBar.setEnabled(false);
switch (progress) {
case 100:
seekBar.setMax(250);
increaseMax = false;
maxPriceView.setText("$" + String.valueOf(seekBar.getMax()));
break;
case 250:
seekBar.setMax(500);
increaseMax = false;
maxPriceView.setText("$" + String.valueOf(seekBar.getMax()));
break;
case 500:
maxPriceView.setText("$500+");
break;
}
seekBar.setEnabled(true);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
increaseMax = true;
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Do nothing
}
}
Further improving my comment, give this a shot
private boolean newTouch = false;
private int oldProgress;
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
if (newTouch) {
oldProgress = progress;
priceView.setText("About how much will it cost? $" + String.valueOf(progress));
if(progress == seekBar.getMax()) {
newTouch = false;
switch (progress) {
case 100:
seekBar.setMax(250);
seekBar.setProgress(100);
maxPriceView.setText("$" + String.valueOf(seekBar.getMax()));
break;
case 250:
seekBar.setMax(500);
seekBar.setProgress(250);
maxPriceView.setText("$" + String.valueOf(seekBar.getMax()));
break;
case 500:
seekBar.setProgress(250);
maxPriceView.setText("$500+");
break;
}
}
} else {
seekBar.setProgress(oldProgress);
}
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
newTouch = true;
}
E/AndroidRuntime(7183): Caused by: java.lang.ClassCastException: android.widget.SeekBar cannot be cast to android.widget.EditText
is this true?
if you can't use a seekbar to change text in a EditText element then what should i use?
a static TextView?
because i need a slider aka SeekBar for my app
thanks in advance
here's the code
private OnSeekBarChangeListener customSeekBarListener = new OnSeekBarChangeListener()
{
// update currentCustomPercent, then call updateCustom
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
// sets currentCustomPercent to position of seekBars's thumb
currentCustomPercent = seekBar.getProgress();
updateCustom(); // updates EditTexts for custom part and Total
} // end method on progressChanged
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
} // end method onStartTrackingTouch
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
}
}; // end onSeekBarChangeListener
the program doesn't error but it force closes... and the logcat say's that this is screwed up.. 6 hours worth of work... down the toilet... #flush
Probably you are casting seekBarobject to editText in method:
onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
If yes, just do the following:
onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
editText.setText(""+progress);
}