Seekbar in Android Studio - java

I came across a piece of code,now I am stuck with it.
SeekBar volumeControl=(SeekBar)findViewById(R.id.volumeSeekBar);
volumeControl.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,progress,0 );
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
Here I know that volumeControl is a variable of type SeekBar. In the second line of code volume control is set with a function setOnSeekBarChangeListener. I am unable to understand what's written inside the brackets of setOnSeekBarChangeListener. Can anyone please explain it in detail. I am just introduced to java and don't have much knowledge

This is a small piece of code to control volume using a seek bar.
Inside the brackets of onSeekBarChangeListener, we declare a new SeekBar.onSeekBarChangeListener which implements three methods :
onProgressChanged : This basically tracks the change in the seek bar and then sets the volume according to the amount of change.
onStartTrackingTouch : This methods contains the code which should be executed when the touch gesture starts.
onStopTrackingTouch:
This method contains the code which should be executed which the touch gesture stops.

Related

Glitches while playing audio in Android

I am using MediaPlayer to play audio in Android. MediaPlayer is working perfectly but when I use a SeekBar which is updated with the duration of audio, the audio doesn't play smoothly and breaks while playing. Below is my code snippet for reference.
mSongSeekBar.setMax(mMediaPlayer.getDuration());
mSongSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mMediaPlayer.seekTo(progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
mSongSeekBar.setProgress(mMediaPlayer.getCurrentPosition());
}
}, 0, 500);
What is the reason for this behavior? How to get rid of this? Should I go with any alternative of Timer?
I had the same problem where the audio was continuously seeking by itself and causing glitches. You need to make sure the audio is seeked only when the user scrubs it and not when it is normally running. For this purpose the boolean fromUser parameter of onProgressChanged is useful. This would ensure the audio seeking only when the user scrubs it.
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser){
mMediaPlayer.seekTo(progress);
}
}
Reason
Audio is not playing continuously, it is changing every 500 millisecond, and so it feels breaking. Because Timer() is changing the value of Progress integer. And mMediaPlayer seeks to it every time automatically, as the code is written:
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mMediaPlayer.seekTo(progress);
}
How to Get rid of this
You should use boolean fromUser to change position of audio, only when user changes seekBar manually, You can do this by just a little change(using if)
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser)
mMediaPlayer.seekTo(progress);
}
You might consider overriding the onStartTrackingTouch and onStopTrackingTouch methods as well. Because when you are dragging the seek-bar the onProgressChanged is called frequently and each time it is trying to set the media player to play from a specific position and hence you are getting that cracking or breaking of your audio.
I would recommend, pausing the media player temporarily while the seek-bar being dragged and resume the audio when you are done with the dragging. The methods mentioned above might help you to achieve those behaviors.

How to constantly update a Text View

I'm trying out making an app using Android Studio and I want to constantly update a text view.
I at first thought I should use a loop but that ended up not even running for some reason.
TextView amount = findViewById(R.id.amountTextView);
final SeekBar seekBar = findViewById(R.id.seekBar);
int p = seekBar.getProgress() + 1;
amount.setText(String.valueOf(p));
});
}
}
With this method it doesn't update the results text view. I would like it to constantly update the text view so it shows what number the seek bar is on.
You will need an event for update the state of SeekBar and TextView, in this case I user a Handler(android.os) for update the views each 100 milliseconds of time, but you can use another event like the load of a web service or another.
In your case, it doesn't update because you just update the state of variable, but never update the state of seekbar, that is the reason it will never increment the current state.
private void startLoopUntilEnd() {
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
#Override
public void run() {
int progress = seekBar.getProgress();
textView.setText(String.valueOf(progress));
progress++;
seekBar.setProgress(progress);
startLoopUntilEnd();
}
};
if (currentState <seekBar.getMax()){
handler.postDelayed(runnable,100);
}
}
You can call this method from onCreate in case of Activity or onResume in case of Fragment and after it will go until the SeekBar is complete recursively.
If you want to change the max of seekBar, you can set it in xml or in code.
Use onSeekBarChangeListener:
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
amount.setTextprogress);
}
});

Android - View.animate skipping

I'm working on animating a View from within a GridLayout. When I access the view from the View.OnClickListener onClick(View view) method the animation runs smoothly.
However, when I get Views via gridLayout.getChildAt(i) the animation skips straight to the ending position.
view.animate()
.translationX(viewAnimation.xTransform)
.translationY(viewAnimation.yTransform)
.setDuration(200)
.setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
//Code
}
#Override
public void onAnimationEnd(Animator animator) {
if (reloadGrid)
//Code
else
animate(viewAnimations);
}
//Other methods here
});
I'm really unsure as to why when the View is passed as a parameter it animates fine, however otherwise it skips.
Any advice would be great!
Edit
I have also checked and the difference between the 2 'View' objects is one has mDrawable set and one doesn't. I believe this could be the cause?
I'm not really sure why this solves the problem, however accessing each View within the GridLayout via findViewById(i) seems to work, and then allow the animation to run smoothly.
This took way too long to figure out.

saving the state of a SeekBar

I'm struggling to find the best way to implement my update to the database
The code below is in the adapter for a list view, so each list item has its own seekbar.
The list is of homework assignments so each item has its own degree of completion which I need to persist to a database.
I have a business method which can do the database write, it just needs the id of the assignment and the new progress value.
private void attachProgressUpdatedListener(SeekBar seekBar) {
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
// need to update database with new progress here!
}
public void onStartTrackingTouch(SeekBar seekBar) {
// empty as onStartTrackingTouch listener not being used in
// current implementation
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// empty as onProgressChanged listener not being used in current
// implementation
}
});
}
the problem I'm having is getting a handle to my AssignmentHandler which deals with the database reads / writes. I can pass the assignment_id to my attachProgressUpdatedListener without any issues but I'm not sure this is the best way to go about it as I haven't got / not sure I want an instance of AssignmentHandler instantiated inside the ArrayAdapter.
You can store the element's database ID in each SeekBar's "tag" (setTag() and getTag() methods), and use that to update the database from the onStopTracking method.

Android dev - Issue with using SeekBar

I'm trying to implement a SeekBar in a simple flashlight app (that I'm learning on) and cannot understand why the app keeps crashing when I set the OnSeekBarChangeListener to my SeekBar. As soon as a remove all of the code inside the onStopTrackingTouch() for the listener, the app runs fine. But if there is anything at all inside the listener's methods, it crashes. I'm also using buttons and gestures in the app and have not had any problems using those.
I am bringing up a separate layout when the user presses the Menu button | Brightness option, which displays the SeekBar (to adjust the brightness)
Here is the how I am implementing the SeekBar:
SeekBar mSeekBar;
...
#Override
public void onCreate(Bundle savedInstanceState){
setContentView(R.layout.main);
...
mSeekBar = (SeekBar)findViewById(R.id.mSeekbar);
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
//first set the brightness mode to manual
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
//change the actual setting
WindowManager.LayoutParams lp = getWindow().getAttributes();
float brightness = Float.valueOf(seekBar.getProgress()); //change the brightness here
lp.screenBrightness = brightness;
getWindow().setAttributes(lp); //set the new brightness
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
});
Thank you for your time and advice.
UPDATE: Here is the link to my Logcat info http://pastie.org/2561098
UPDATE 2: Here is the link to my release run LogCat info: http://pastie.org/2561111
SOLVED:
I had mSeekBar being instantiated and the listener's set before the layout was present. The SeekBar was null because the separate layout I made for adjusting the brightness was not currently in view. Putting the instantiation and listener's inside the switch statement I use for options menu, after the new layout (for the brightness) is set works perfectly.
Thank you!
There is your answer. On line 77 of your onCreate method your program is crashing because of a NullPointerException. The answer is in the stack trace, while these look perplexing, they actually point you to the exact line of code that caused the crash (most of the time).
at com.polaniec.myflashlight.MyFlashLightActivity.onCreate(MyFlashLightActivity.java:77)
When you dig through the stack trace you want to look for the part that indicates YOUR actual class name and method name (not all of the android.os... or java.lang... methods). The 77 means it is line 77 in your code. Whatever you are referencing is null, maybe it was not instantiated?
Hope this helps!

Categories

Resources