In my application , i m applying an animation on layout. This animation put the layout off the screen and put it in from the other side :
private void slideAnimation(final int sens)
{
Animation animOut = null;
if(sens == -1) {
animOut = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_out_left);
} else {
animOut = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_out_right);
}
animOut.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
Animation animIn = null;
if(sens == -1) {
animIn = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_in_right);
} else {
animIn = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_in_left);
}
camLayout.startAnimation(animIn);
}
});
camLayout.startAnimation(animOut);
}
When needed i simply call slideAnimation().
It's working fine , but sometime we can see animation in a runnable. Should i consider using an other solution to slide out and in my layout or my code is OK ?
Thanks
seems ok to me! I gather you are just trying to schedule one animation to play after the another. And this code will do the job. I am not sure but i suppose the animation end listener does already listen from a different thread. So i don't think a new thread is required.
IF this code is working as per your expectation then it's well and good. The problem with runnable is it will create on more process separately parallel to main thread and it will eat up main thread's memory and it will make your UI performance weak.
Related
I am making an application on Android which generates one of the two available images on clicking a button and after a duration of 1 second, that image is supposed to fade away, giving the user a choice to click the button again.
The problem is that the animation works smoothly on the first button press (i.e. generates an image and then fades away), however on the second button press, the image just sits there and nothing happens. I can't figure out why.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView firstimage = (ImageView)findViewById(R.id.imageView2);
final ImageView secondimage = (ImageView)findViewById(R.id.imageView1);
final Button clickMe = (Button)findViewById(R.id.button);
final TextView image_description = (TextView)findViewById(R.id.textView);
image_description.setText("");
final Animation fadeout = new AlphaAnimation(1,0);
fadeout.setStartOffset(1000);
fadeout.setDuration(1000);
secondimage.setAnimation(fadeout);
firstimage.setAnimation(fadeout);
image_description.setAnimation(fadeout);
secondimage.setVisibility(View.GONE);
firstimage.setVisibility(View.GONE);
image_description.setVisibility(View.GONE);
clickMe.setVisibility(View.VISIBLE);
fadeout.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation) {
System.out.println("Animation block");
secondimage.setVisibility(View.GONE);
firstimage.setVisibility(View.GONE);
image_description.setVisibility(View.GONE);
clickMe.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) { }
});
clickMe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
System.out.println("Click block");
Random r = new Random();
int i = r.nextInt(2);
clickMe.setVisibility(View.GONE);
if(i == 0) {
secondimage.setVisibility(View.VISIBLE);
image_description.setText("LOOK it's a CAT");
image_description.setVisibility(View.VISIBLE);
secondimage.setAnimation(fadeout);
image_description.setAnimation(fadeout);
} else {
firstimage.setVisibility(View.VISIBLE);
image_description.setText("LOOK it's a DOG");
image_description.setVisibility(View.VISIBLE);
firstimage.setAnimation(fadeout);
image_description.setAnimation(fadeout);
}
}
});
}
The Logs look something like this:
Click Block
Animation Block
Click Block
Click Block
Click Block
Click Block
Any idea why the code is not reaching the Animation block on 2nd click onwards?
Alright. I was able to solve my own query.
I replaced
secondimage.setAnimation(fadeout);
with
secondimage.startAnimation(fadeout);
On doing so, the code was able to reach the onAnimationEnd function.
The easiest thing to do is create/inflate a new instance of the Animation type object for each view that needs animation. As you have it now, it's trying to reuse the same object.
I want to make 2 animations on one View, with the second one starting after the first one. The first one is translating and I use TranslateAnimation for that purpose and the second one is AlphaAnimation as I want the View to start blinking after translation. The problem is no matter what I'm doing these animations start simultaneously. As far as I'm concerned I should use AnimationSet object for this purpose but how to do this exactly? I even tried to use setStartTime() method to use some crazy value for the AlphaAnimation before putting it into AnimationSet but still the animations start immediately and simultaneously. So what should I do to prevent it from happening?
PS Here is what I tried to do and what didn't work:
TextView cursor = (TextView) findViewById(R.id.cursor);
Animation tAnim = new TranslateAnimation(-1000.f,200.0f,0.0f,0.0f);
tAnim.setStartTime(0);
tAnim.setDuration(3000);
tAnim.setStartOffset(0);
Animation bAnim = new AlphaAnimation(1.0f, 0.0f);
bAnim.setStartTime(tAnim.getDuration());
bAnim.setDuration(300);
bAnim.setStartOffset(30);
bAnim.setRepeatCount(Animation.INFINITE);
bAnim.setRepeatMode(Animation.REVERSE);
AnimationSet s = new AnimationSet(false);
s.addAnimation(tAnim);
s.addAnimation(bAnim);
cursor.startAnimation(s);
you can use this
TextView cursor = (TextView) findViewById(R.id.cursor);
Animation tAnim = new TranslateAnimation(-1000.f,200.0f,0.0f,0.0f);
tAnim.setStartTime(0);
tAnim.setDuration(3000);
tAnim.setStartOffset(0);
Animation bAnim = new AlphaAnimation(1.0f, 0.0f);
bAnim.setStartTime(tAnim.getDuration());
bAnim.setDuration(300);
bAnim.setStartOffset(30);
bAnim.setRepeatCount(Animation.INFINITE);
bAnim.setRepeatMode(Animation.REVERSE);
tAnim.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation arg0) { }
#Override
public void onAnimationRepeat(Animation arg0) { }
#Override
public void onAnimationEnd(Animation arg0) {
cursor.startAnimation(bAnim);
}
});
cursor.post(new Runnable() {
#Override
public void run() {
cursor.startAnimation(tAnim);
}
});
Make sure that cursor and tAnim are instance/global variable in your class, and also start the animation in the post method of the TextView to run it in synchronize with the textView
Use animation listener. hope this works
Animation tAnim = new TranslateAnimation(-1000.f,200.0f,0.0f,0.0f);
tAnim.setStartTime(0);
tAnim.setDuration(3000);
tAnim.setStartOffset(0);
Animation bAnim = new AlphaAnimation(1.0f, 0.0f);
bAnim.setStartTime(tAnim.getDuration());
bAnim.setDuration(300);
bAnim.setStartOffset(30);
bAnim.setRepeatCount(Animation.INFINITE);
bAnim.setRepeatMode(Animation.REVERSE);
AnimationListener AnimationListener = new AnimationListener(){
#Override
public void onAnimationStart(Animation animation) {
// TODO Animation start and end
}
#Override
public void onAnimationEnd(Animation animation) {
//start the second animation here
yourview.startAnimation(bAnim);
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}};
tAnim.setAnimationListener(AnimationListener);
yourview.startAnimation(tAnim);
tAnim.hasEnded();
I've an activity that loads the resources and shows the message "Please wait, loading", and when all resources are loader, the textview changes to "Ready" and change the views of the activity. The problem is that I want to wait for the animation end, but the views are removed even before they start. How can I wait for that?
tview1.startAnimation(desvanecer); tview2.startAnimation(desvanecer);
tview1.setText(R.string.ready);
tview2.setText(R.string.launcher_continue);
tview1.startAnimation(aparecer);
tview2.startAnimation(aparecer);
layout = (RelativeLayout) findViewById(R.id.launcher_layout);
screen = new Screen(context);
thread = new Thread(screen);
layout.removeAllViews();
layout.addView(screen);
thread.start();
You can perform your removals at the end of the animation by using an animation listener and doing them onAnimationEnd
desvanecer.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
//REMOVAL OR OTHER CODE HERE
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
What you need is an AnimationListener and implement the onAnimationEnd method. But have a look at my comment and the doubts I have about your code.
I have been working on trying to get an Activity to not show until data has been selected and is ready for display: Prevent screen display until after fetching data
Finally got it to work with the aid of themes.
Now I have another problem.
I need to animate the transition from one Activity to the next.
I know how to use overridePendingTransition but this won't work here since I am already in the target Activity when I want to do the animation.
The only reason I can see the other one is because the current one is transparent.
I have no problem sliding in the new one:
View view = getLayoutInflater().inflate(R.layout.content_screen, null);
view.startAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_in_right));
setContentView(view);
However, I can't think of any way to get the old one to slide out.
Any ideas anyone?
Create a "slide out left" animation. Then adjust your animation for the new view, so when the animation starts, you apply and start the other animation to the other view. E.g.,
Animation animation = AnimationUtils.loadAnimation(context,
R.anim.slide_in_right);
animation.setDuration(TIME);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO - Set and start other animation here
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
});
view.startAnimation(animation);
[Edit]
// First, define and infalte the view that will be incoming
View upcomingView = inflater.inflate(...);
// Next, we'll set the animation up
Animation animation = AnimationUtils.loadAnimation(context,
R.anim.slide_in_right);
animation.setDuration(TIME);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Animation outAnimation = AnimationUtils.loadAnimation(context,
R.anim.slide_out_left);
upcomingView.startAnimation(outAnimation);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
});
currentView.startAnimation(animation); // This will start the animation defined above, which will also set and start the animation for the incoming object
I am animating an ImageView so that when you click the image the animation occurs (then later it resets) but my problem is that if you click again where the image sat originally - the animation starts from the beginning right away with out finishing (it just resets and starts again.
so I tried using
setEnabled(false)
which works great, the animation continues on its path up perturbed by any random clicking, now the only problem is getting the ImageView enabled again - at about the same time as the animation stops
here's what i have
stopImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
mpButtonClick.start();
stopImage.setEnabled(false);
TranslateAnimation anim = new TranslateAnimation(0f,250 + Math.round(Math.random() * (-700)),0f,-300f);
anim.setDuration(4200);
anim.setRepeatCount(0);
stopImage.startAnimation(anim);
now is there an easy way i can call setEnabled(true) after a some time has passed?
You could try using an AnimationListener and then calling setEnabled(true) from onAnimationEnd().
Something like this:
stopImage.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
mpButtonClick.start();
TranslateAnimation anim = new TranslateAnimation(0f,250 + Math.round(Math.random() * (-700)),0f,-300f);
anim.setDuration(4200);
anim.setRepeatCount(0);
anim.setAnimationListener(new Animation.AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
stopImage.setEnabled(false);
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
#Override
public void onAnimationEnd(Animation animation)
{
stopImage.setEnabled(true);
}
});
stopImage.startAnimation(anim);
}
}
Here's the documentation for AnimationListeners.