I'm trying to have two animations occur in one activity with the first happening first and only once it's done, does the second start. The ObjectAnimator moves the imageView up the screen using the .ofFloat() method and then I want a loading animation which loops through several image files to create a loading-like effect.
This is my code:
//Animations
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
//Change cloud from sleeping to awake/happy
g2ndSleepingClouds.setBackgroundResource(R.drawable.clouds_happy_formatted);
//Move image view 250 pixels up the screen vertically
ObjectAnimator animation1 = ObjectAnimator.ofFloat(g2ndSleepingClouds, "translationY", -250f);
animation1.setDuration(1000);
animation1.start();
//Loading animation
loadingImageView.setBackgroundResource(R.drawable.loading_1);
loadingAnimation = (AnimationDrawable) loadingImageView.getBackground();
loadingAnimation.stop();
loadingAnimation.start();
}
}, 1000);
The error I get in Logcat is:
"android.graphics.drawable.BitmapDrawable cannot be cast to android.graphics.drawable.AnimationDrawable"
Any help?
Related
I am creating like a Whack a Molee type of game, and I am creating imageviews at random positions on the screen.
The thing is, I am adding a postdelayed to a var I am creating every two seconds ( the var is the imageview) but it only acts to the last imageview created. It happens because every two seconds that var is replaced with a new instance of imageview.
How can I add an independent postdelayed or something that detects when 2 seconds has passed and removing that specific imageview.
Thanks!
mv = new ImageView(this);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mv.setVisibility(View.GONE);
}
}, 2000);
I tried this, but only removes the very last imageview.
public void createImage() {
final ImageView mv = new ImageView(this);
// Do all your positioning and sizing (layout params) setting stuff here
new Handler(getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
mv.setVisibility(View.GONE);
}
}, 2000);
}
Simply don't override the value every time, by using a local varaible inside a method.
This way the mv instance will be the same in the runnable which is executed by the handler.
(And also don't create a handler every time)
(You could also draw the entire thing on a canvas)
I have a spinning wheel, which is an ImageView, in my app, and the animation is working well, but the issue is for just a split second it snaps back to it's original position (0 degree rotation). The .gif below shows what I am talking about.
The last split second of the rotation it has that awkward snap back that makes the animation look extremely unsmooth.
I am looking for a way to fix this but I cannot quite figure it out. This is my code right now that animates the ImageView and rotates it to the final position of the animation
ImageView readyButton = findViewById(R.id.spinnerready);
final ImageView spinnerSpin = findViewById(R.id.spinnerspin);
final Animation animRotate = new RotateAnimation(ROTATE_FROM, ROTATE_TO, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animRotate.setDuration(5000);
animRotate.setRepeatCount(0);
readyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
float newDeg = ROTATE_TO;
spinnerSpin.startAnimation(animRotate);
spinnerSpin.postDelayed(new Runnable() {
#Override
public void run() {
spinnerSpin.setRotation(ROTATE_TO);
}
}, 5000);
while(newDeg > 360) {
newDeg = newDeg - 360;
}
}
});
I have also tried changing the delay of the rotation to 4500 instead of 5000 but the issue is not fixed. Is there a way to eliminate the ImageView from going back to its original position after the animation?
I am trying to execute an animation in which I have two fragments stacked on top of each other.
The top fragment is a details fragment.
the bottom fragment is a menu list view fragment.
I did this by creating two overlapping framelayouts in the activity layout. I want to be able to do an animation in which the background fragment would be revealed in a fashion similar to a door opening leaving only 20 percent of the edge of the top fragment in view.
I tried doing this animation with the standard view animation library available to API 9 but it seemed that only the pixels were moved and but the touch mapping still corresponded to the top fragment and the bottom menu fragment could not be accessed.
So I downloaded the nineoldandroids library and tried to user AnimatorSet with ObjectAnimators to do the animation... except this time when the fragment is animated away it reveals only a gray background rather than the fragment in the back like before.
This is a code snippet on how I tried to implement a simple translation to reveal the background fragment
private void animateFragmentOut() {
activeFragment = (Fragment)getSupportFragmentManager().findFragmentById(R.id.nav_item_fragment_container);
View myView = activeFragment.getView();
AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(myView, "translationX", 0, 230)
);
set.setDuration(500).start();
}
Why is the background fragment not shown when I use this animation?
How do I use nineoldandroids to reveal the background fragment properly?
I ended up solving this problem by using a listener to inflate the background view right at the start of the animation using the following code
private void animateFragmentOut() {
activeFragment = (Fragment)getSupportFragmentManager().findFragmentById(R.id.nav_item_fragment_container);
View myView = activeFragment.getView();
Animator.AnimatorListener listener = new AnimatorListenerAdapter() {
#Override
public void onAnimationStart(Animator animation) {
launchNavigationFragment();
}
#Override
public void onAnimationEnd(Animator animation) {
}
};
ObjectAnimator rotateY = ObjectAnimator.ofFloat(myView,"rotationY",-15f);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(myView,"scaleX",0.8f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(myView,"scaleY", 0.8f);
ObjectAnimator translateX = ObjectAnimator.ofFloat(myView,"translationX",400f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(rotateY,scaleX,scaleY,translateX);
animatorSet.addListener(listener);
animatorSet.setDuration(700);
animatorSet.start();
}
Saldy despite this working great on API levels 11> and up on my API 9 device I am still having the same problem I had with the standard animation library. The view pixels translate but the touch areas stay mapped in the same place. So I cannot interact with the background navigation menu fragment.
Am quite new to Android, I could not found a thread on how to start new activity on anim end.
Here is my code:
public class Intro extends Activity {
AnimationDrawable anim = new AnimationDrawable();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.intro);
ImageView iv =(ImageView) findViewById(R.id.imageView1);
iv.setBackgroundResource(R.anim.animation);
anim = (AnimationDrawable) iv.getBackground();
iv.post(new Runnable(){
public void run(){
anim.start();
}
});
}
}
As far as I know there is no callback mechanism to determine when an AnimationDrawable has finished an iteration. What you can do is to query the number of frames and the delay of each frame. Sum that up and make a delayed post with that duration. In that callback you can start your second activity.
And note that it is a bit dangerous to start the animation the way you do it. The docs say:
It's important to note that the start() method called on the AnimationDrawable cannot be called during the onCreate() method of your Activity, because the AnimationDrawable is not yet fully attached to the window. If you want to play the animation immediately, without requiring interaction, then you might want to call it from the onWindowFocusChanged() method in your Activity, which will get called when Android brings your window into focus.
I have an onClick method set in the xml layout file that triggers the vibration of the phone for 100ms at this point I have the ImageView Visibility set to visible so it can be seen. I want the ImageView to be set back to gone again when the vibration has stopped. How do I go about this?
You can start this method at the same time:
public void timerDelayRemoveView(float time, final ImageView v) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
v.setVisibility(View.GONE);
}
}, time);
}