I have been working on a little game and I need a progress bar animation, which begins when I touch a button for the first time and if I touch the button again before the animation ended the progressbar needs to reset.
In my code animation.start(); works well but the animation.cancel() does not seem to work.
French Version of this Question
My Activity Code containing the line that does not work:
public class MainActivity extends Activity {
Button b_bleu;
PrgressBar bar1;
#Override
public void onWindowFocusChanged(boolean hasFocus) {
b_bleu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ObjectAnimator animation = ObjectAnimator.ofInt(bar1, "progress", 100, 0);
animation.setDuration(5000);
animation.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
}
#Override
public void onAnimationEnd(Animator animator) {
//application se termine
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
});
animation.cancel();
animation.start();
}
});
}
I think the problem is that animation.cancel() has no effect since you call animation.start(); right after it.
Try something like this:
Declare a field:
private boolean mStarted = false;
Then set it in animation callbacks and check its value:
animation.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
mHasStarted = true;
}
#Override
public void onAnimationEnd(Animator animation) {
mHasStarted = false; // reset the field value so that it can be started again onClick once it has ened
}
#Override
public void onAnimationCancel(Animator animation) {
mHasStarted = false;
}
});
if (mStarted) {
animation.cancel();
} else {
animation.start();
}
Hope this helps!
Related
This is the code:
//These are the animations of the Menu button getting bigger and smaller
final ScaleAnimation MenuScaleBigger = new ScaleAnimation(1f, 1.1f, 1f, 1.1f,1,0.5f,1,0.5f);
MenuScaleBigger.setDuration(400);
final ScaleAnimation MenuScaleSmaller = new ScaleAnimation(1.1f, 1f, 1.1f, 1f,1,0.5f,1,0.5f);
MenuScaleSmaller.setDuration(400);
MenuScaleBigger.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
Menu.setScaleX(1.1f);
Menu.setScaleY(1.1f);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
MenuScaleSmaller.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
Menu.setScaleX(1f);
Menu.setScaleY(1f);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
//This is the click listener that starts the animation of getting bigger
Menu.setOnClickListener(new View.OnClickListener() {
int counter = 0;
#Override
public void onClick(View v) {
if(counter == 0){
Menu.startAnimation(MenuScaleBigger);
counter++;
}
else{
Menu.startAnimation(MenuScaleSmaller);
counter--;
}
}
});
I think that the bouncing happens because of the Menu.ScaleX(); and Menu.ScaleY(); , but I need some way of making the animation stay in the last frame.
What I want is that if I click the Menu Imageview it becomes bigger, and stays bigger, and if I press it again it becomes smaller going back to the original size.
Remove the AnimationListeners and add these two lines
MenuScaleBigger.setFillAfter(true);
MenuScaleSmaller.setFillAfter(true);
setFillAfter(true); makes sure that the View stays in the position after animation and doesn't come back to it's base position
Im making a simple radio streaming app. Everything works great but having a few buggy issues.
When i press the home screen of my device i want the radio to carry on playing. which it does, But as soon as i go to my app history and re-open the app. It starts a new session. this make for a very Un-Pleasurble piece of music lol.
The app is very simple in the way it works i have a media player and a media controller which is attached to a surfaceView in my xml.
Can some one please tell me the correct way to fix this issue as this is the first time making an app that contains a live stream.
Thanks as always guys
my code for the media player and controller
public class radiostation extends AppCompatActivity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener,
MediaController.MediaPlayerControl {
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private MediaPlayer mediaPlayer;
private MediaController mediaController;
private Handler handler = new Handler();
String videoSource =
"my radio station source address";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radiostation);
surfaceView = (SurfaceView)findViewById(R.id.surface);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(mediaController != null){
mediaController.show();
}
return false;
}
});
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Toast.makeText(radiostation.this,
"Media Controls active lets mash it up", Toast.LENGTH_LONG).show();
mediaPlayer = new MediaPlayer();
mediaPlayer.setDisplay(surfaceHolder);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnPreparedListener(this);
try {
mediaPlayer.setDataSource(videoSource);
mediaPlayer.prepare();
mediaController = new MediaController(this);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(radiostation.this,
"Radio Station off Air or no internet connection!\n" + e.toString(),
Toast.LENGTH_LONG).show();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
Toast.makeText(radiostation.this,
"You are now connected ", Toast.LENGTH_LONG).show();
mediaController.setMediaPlayer(this);
mediaController.setAnchorView(surfaceView);
handler.post(new Runnable() {
public void run() {
mediaController.setEnabled(true);
mediaController.show();
}
});
}
#Override
public void start() {
mediaPlayer.start();
}
#Override
public void pause() {
mediaPlayer.pause();
}
#Override
public int getDuration() {
return mediaPlayer.getDuration();
}
#Override
public int getCurrentPosition() {
return mediaPlayer.getCurrentPosition();
}
#Override
public void seekTo(int pos) {
mediaPlayer.seekTo(pos);
}
#Override
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
#Override
public int getBufferPercentage() {
return 0;
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return false;
}
#Override
public boolean canSeekForward() {
return false;
}
#Override
public int getAudioSessionId() {
return mediaPlayer.getAudioSessionId();
}
#Override
public void onBackPressed() {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
finish();
}
I made a button for Android that rotates on click, but when I set a button and new activity, when I click it's just set me to new activity.
I need just this: when I click on that button, first to do animation e.g. rotate, then to execute a new activity. Here is my code:
ImageButton pandaButton2 = (ImageButton) findViewById(R.id.pandaButton2);
pandaButton2.setOnClickListener(new OnClickListener(){
public void onClick(View v){
v.startAnimation(pandarotate);
startActivity(new Intent("com.example.threepandas.MENU"));
}
});
You can set animation listener, when finish animation start your activity.
Please refer this link
Example code (must update based on your purpose):
ImageButton pandaButton2 = (ImageButton) findViewById(R.id.pandaButton2);
pandaButton2.setOnClickListener(new OnClickListener(){
public void onClick(View v){
v.startAnimation(pandarotate);
}
});
pandarotate.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
startActivity(new Intent("com.example.threepandas.MENU"));
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
insert a delay for the length of the animation after the animation starts and before the activity starts
try {
Thread.sleep(1000); //1000 milliseconds is one second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
Here is the solution I use for this problem (got it from the Google I/O App Source Code on Github)
private static final int DELAY = 250;
private Handler mHandler;
#Override
public void onClick(final View view) {
switch (view.getId()) {
case R.id.button:
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
}
}, DELAY);
break;
}
}
I have seen a lot of answers but doesn't seems to find one. I am using new FAB in one of my fragments and want to remove it when that particular fragment goes to backstack, but I am not sure which method in fragment gets called when it is added to back stack and replaced by other fragment.
Following methods were called whenever the Fragment is replaced or added to backstack
1) onPause()
2) onStop()
3) onDestroyView()
call your FAB removing method in any one of the above methods in your Fragment.
http://developer.android.com/guide/components/fragments.html#Creating
Here is my suggestion -
First, add the animation code and backstack listener in your Activity:
public class MainActivity extends AppCompatActivity
implements FragmentManager.OnBackStackChangedListener {
private FloatingActionButton mFab;
private Animation mShowFab;
private Animation mHideFab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportFragmentManager().addOnBackStackChangedListener(this);
mShowFab = AnimationUtils.makeInAnimation(this, false);
mShowFab.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
mFab.setVisibility(View.VISIBLE);
}
});
mHideFab = AnimationUtils.makeOutAnimation(this, true);
mHideFab.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
mFab.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
});
}
public void showFab(boolean show) {
boolean visible = mFab.isShown();
if (show) {
if (!visible)
mFab.startAnimation(mShowFab);
} else {
if (visible)
mFab.startAnimation(mHideFab);
}
}
And then - depending on backstack depth - show or hide the FAB:
#Override
public void onBackStackChanged() {
showFab(getSupportFragmentManager().getBackStackEntryCount() > 0);
}
I've been looking around and the main ways seem to be setting an animation listener on the object. However I have set an animation listener and the animation complete callback does not fire.
Do you know how I can get the callback when an view.animate().translationY() has finished its animation?
root.setLayoutAnimationListener
(
new Animation.AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
}
#Override
public void onAnimationEnd(Animation animation)
{
closeFragmentAnimationComplete(); //is not called
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
}
);
root.animate().translationY(100);
Please try:
view.animate().translationY(100).setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {}
#Override
public void onAnimationEnd(Animator animation) {
closeFragmentAnimationComplete();
}
#Override
public void onAnimationCancel(Animator animation) {}
#Override
public void onAnimationRepeat(Animator animation) {}
});