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;
}
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();
});
This is my code i use to setup a 5 band Equalizer, but i would like to have a Layout which supports the number of equalizer bands supported by the device.
For now i have hardcoded the size of Equalizer bands because i'm not sure how to create a Layout for a non constant value of equalizer bands.
This is the code i would like to use:
equalizer.getNumberOfBands(); //it tells you the number of equalizer in device.
But what if a device supports +10 equalizer bands, how can i fit those bands on the screen?
Code for creating Equalizer
private void setupEqualizer(){
mEqualizer = new Equalizer(0, mediaPlayer.getAudioSessionId());
final short lowerEqualizerBandLevel = mEqualizer.getBandLevelRange()[0];
final short upperEqualizerBandLevel = mEqualizer.getBandLevelRange()[1];
for (short i = 0; i < 5; i++){
final short equalizerBandIndex = i;
int freq_range = mEqualizer.getCenterFreq(equalizerBandIndex);
verticalSeekbar[i].setMax(upperEqualizerBandLevel - lowerEqualizerBandLevel);
verticalSeekbar[i].setProgress(mEqualizer.getBandLevel(equalizerBandIndex));
verticalSeekbar[i].setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
mEqualizer.setBandLevel(equalizerBandIndex, (short) (progress + lowerEqualizerBandLevel ));
slider_value[equalizerBandIndex].setText(String.valueOf((progress + lowerEqualizerBandLevel) / 100 + " dB"));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
slider_labels[i].setText(formatBandLabel(freq_range));
float scale2 = getResources().getDisplayMetrics().density;
int dpAsPixels2 = (int) (8*scale2 + 0.5f);
}
setupEqSpinner();
}
You need to use Vertical SeekBar as told by Nilesh
equalizer.getNumberOfBands() // it tells the number of equalizer ..
Create a LinearLayout(Horizontal) and add Vertical Seekbar to it in a for loop (numberOfBands)..
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
In my android app, I'm trying to check whether a boolean has changed and if it has then do something. But it's not constantly checking it. I believe I need a listener, but I'am unaware on how to structure it or where to put it. I've looked online and can really only find onClicks etc, no boolean ones.
Here is what I have so far:
public boolean gameStartTouch = false;
public boolean titleVisible = true;
/*
public boolean isJumping = false;
public boolean isGrounded = false;
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_main);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
if (gameStartTouch == false) {
gameStartTouch = true;
titleVisible = false;
}
break;
}
return true;
}
and this is what needs to go in the listener:
ImageView titleView = (ImageView) findViewById(R.id.titleImg);
ImageView startNotifView = (ImageView) findViewById(R.id.startNotifImg);
if (titleVisible == false) {
titleView.setVisibility(View.INVISIBLE);
startNotifView.setVisibility(View.INVISIBLE);
} else {
titleView.setVisibility(View.VISIBLE);
startNotifView.setVisibility(View.VISIBLE);
}
Thanks in advance. I couldn't find much info on it for these circumstances specifically.
Do some modifying to your code, manage it like so
#Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
titleView.setVisibility(View.INVISIBLE);
startNotifView.setVisibility(View.INVISIBLE);
break;
}
return true;
}
I would put your findViewById() calls in onCreate to avoid unnecessary resource fetching. The only thing I see is that you are only actually switching your booleans once. Is there any other time you plan to reset gameStartTouch to false and titleVisible to true after the first touch?
#fire_head you can simply declare titleView and startNotifView as your class private members. Initialize them in onCreate method like this:
ImageView titleView = (ImageView) findViewById(R.id.titleImg);
ImageView startNotifView = (ImageView) findViewById(R.id.starting);
and access them in handleGameStartTouch method.
Sorry, I had to post it as an answer as I couldn't comment on the answer above.
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;
}
}