I want to implement 3d flip animation on two image views inside a fragment.
I have two images of a human body i.e. front and back. What I want is to flip the front image to the back when user clicks on a button. And all these things are inside a tab fragment.
I am searching for this from more than 1 hour but didn't get anything useful.
I got some results related to hoe to implement 3d flip animation with fragments inside it but didn't get anything related to what I want.
Please can anyone help me with this?
Thanks
I think you are looking something like this.
image1 = (ImageView) findViewById(R.id.ImageView01);
image2 = (ImageView) findViewById(R.id.ImageView02);
image2.setVisibility(View.GONE);
image1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (isFirstImage) {
applyRotation(0, 90);
isFirstImage = !isFirstImage;
} else {
applyRotation(0, -90);
isFirstImage = !isFirstImage;
}
}
});
private void applyRotation(float start, float end) {
// Find the center of image
final float centerX = image1.getWidth() / 2.0f;
final float centerY = image1.getHeight() / 2.0f;
// Create a new 3D rotation with the supplied parameter
// The animation listener is used to trigger the next animation
final Flip3dAnimation rotation =
new Flip3dAnimation(start, end, centerX, centerY);
rotation.setDuration(500);
rotation.setFillAfter(true);
rotation.setInterpolator(new AccelerateInterpolator());
rotation.setAnimationListener(new DisplayNextView(isFirstImage, image1, image2));
if (isFirstImage)
{
image1.startAnimation(rotation);
} else {
image2.startAnimation(rotation);
}
}
you can find the complete source from here
http://www.inter-fuser.com/2009/08/android-animations-3d-flip.html
Hope it may help you.Good luck
"Flip" animations are fairly straightforward with ObjectAnimator. An example implementation could be:
ObjectAnimator animator = ObjectAnimator.ofFloat(mImageView, "rotationY", 0F, 360F);
animator.setDuration(1000);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.start();
This should flip your ImageView and give you somewhere to start.
Edit: You could perhaps flip the first ImageView by 180F (so that it effectively becomes invisible), then use an AnimatorListener to start another flip on the second ImageView, also by 180F, so it appears one image has transitioned into the other.
Related
I am trying to learn a little bit about animations and so decided to get an ImageView to go across the screen from left to right, which I achieved with:
TranslateAnimation mAnimation = new TranslateAnimation(0, 180, 0, 0);
mAnimation.setDuration(1000);
mAnimation.setFillAfter(true);
mAnimation.setRepeatCount(-1);
mAnimation.setRepeatMode(Animation.REVERSE);
myImageView.setAnimation(mAnimation);
So, I decided to take on a new challenge. Once the image has gone from left to right, I wanted to try and get the image to return to the start position by arching back from right to left to its starting position (basically, a complete semi-circle). However, once the image has reached the end of the x-axis at position 180, I get stuck.
After reading about different methods for animation, I opted to try out ValueAnimator:
ValueAnimator animator = ValueAnimator.ofFloat(0, 1); // values from 0 to 1
animator.setDuration(1000); // 1 seconds duration from start to end position
animator.setRepeatCount(-1);
animator.setRepeatMode(ValueAnimator.REVERSE);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (Float) (animation.getAnimatedValue());
myImageView.setTranslationX((float)(180.0 * Math.sin(value*Math.PI)));
myImageView.setTranslationY((float)(80.0 * Math.cos(value*Math.PI)));
}
});
animator.addListener(new AnimatorListenerAdapter()
{
#Override
public void onAnimationEnd(Animator animation)
{
// done
}
});
animator.start();
However, I am unable to get the positioning correct. I do have a semi-circle (good), however, it is moving the image like a backward C rather than a straight line left to right and then arching back to its starting position (bad).
I am not sure if I should be using AnimatorSet to link the left to right movement and the arching back movement together to create one whole animation...
Can anyone give me some guidance on how to achieve what I have described?
I'm working on a project that calls for the navigation bar to be implemented in a fashion similar to how the Zazzle application does their navigation bar. Animations are not my expertise so I would like to get some ideas from the dev community on how such an animation can be implemented.
This is an image of the navigation drawer, notice how the previous fragment stays in view on the left.
Zazzle_navigation_Drawer
This is a screen shot of the nav transition when the menu button is pressed. It turns and tucks its self away in the right hand side of the screen and when the menu is dismissed it reverses that process.
Zazzle_nav_transition
I'm looking for a suggestion on how this might be implemented and maybe some resources I should look into using or information to learn in order to have a good shot of replicating this effect.
What I've done so far.
I have watched and took notes on the Sliding Animations DevBytes video.
So my strategy thus far is to make the navigation a fragment along with all my other screens and try and implement some sliding animations between them. I think this should give me the basic foundation.
Therefore I am more asking about how the animation would be constructed. I've never done animations before so I am asking for some help in the regards of how custom animations are implemented in android generally and a suggestion on how animation would be done in this case specifically
If anyone stumbles upon this...
I figured this out by using the sample project from the Android developer training website. I created an anim folder in res and adding xml set files with the Object animator tag. I didnt understand how to manipulate the values correctly to get the desired animation but after some poking around i realized the following
<objectAnimator
android:valueFrom=
android:valueTo=
android:propertyName="
android:interpolator=
android:duration= />
The valueFrom tag and the valueTo tag define the points the animation runs between and android fills in the rest. The property name is used to describe what kind of motion is being manipulated (translationX, translationY, rotationX, translationY, scaleX and scaleY). The interpolator sets the rate of change of the animation and finally duration specifies how long the animation should take.
Once the animation files are made the following code can be used to set the animations on the fragments during a transaction.
getFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.exampleOut, R.animator.exampleIn,
R.animator.exampleOut, R.animator.exampleIn,
).add(R.id.container, new mFragment()).addToBackStack(null).commit();\
the first two parameters of setCustomAnimations() set the motion of the two fragments when the transaction is initiated and the last two parameters set the motion of the two fragments when the transaction is reversed, i.e., the back button is pressed.
This can be used to achieve the desired animation however I found that the outbound fragment would disappear from view for some reason. There fore I had to use AnimatorListener as follows:
Animator.AnimatorListener listener = new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator arg0) {
getFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.exampleOut, 0,
0, R.animator.exampleIn
)
.add(R.id.container, new mFragment())
.addToBackStack(null)
.commit();
}
};
slideback(listener);
mHandler.post(new Runnable() {
#Override
public void run() {
invalidateOptionsMenu();
}
});
}
private void slideback(Animator.AnimatorListener listener) {
View movingFragmentView = cardFrontFragment.getView();
PropertyValuesHolder rotateY = PropertyValuesHolder.ofFloat("rotationY", 15f);
PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.8f);
PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.8f);
PropertyValuesHolder translateX = PropertyValuesHolder.ofFloat("translationX", 500f);
ObjectAnimator movingFragmentAnimator = ObjectAnimator.
ofPropertyValuesHolder(movingFragmentView, rotateY, scaleX, scaleY, translateX);
ObjectAnimator movingFragmentRotator = ObjectAnimator.
ofFloat(movingFragmentView, "rotationY",15f, 0f);
movingFragmentAnimator.setDuration(DURATION_TIME);
movingFragmentRotator.setStartDelay(DELAY_TIME);
AnimatorSet s = new AnimatorSet();
s.playTogether(movingFragmentAnimator, movingFragmentRotator);
s.addListener(listener);
s.start();
}
private void slideForward (Animator.AnimatorListener listener) {
View movingFragmentView = cardFrontFragment.getView();
PropertyValuesHolder rotateY = PropertyValuesHolder.ofFloat("rotationY", 15f);
PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
PropertyValuesHolder translateX = PropertyValuesHolder.ofFloat("translationX", 0f);
ObjectAnimator movingFragmentAnimator = ObjectAnimator.
ofPropertyValuesHolder(movingFragmentView, rotateY, scaleX, scaleY, translateX);
ObjectAnimator movingFragmentRotator = ObjectAnimator.
ofFloat(movingFragmentView, "rotationY",15f, 0f);
movingFragmentAnimator.setDuration(DURATION_TIME);
movingFragmentRotator.setStartDelay(DELAY_TIME);
movingFragmentRotator.setDuration(DURATION_TIME);
AnimatorSet s = new AnimatorSet();
s.playTogether(movingFragmentAnimator, movingFragmentRotator);
s.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mShowingBack = false;
}
});
s.start();
}
This allows you to set the properties for the outbound fragment dynamically during runtime and for some reason allows the fragment to remain in view.
In my app, I'm rotating an image on a button click. Now when I pass the image to another activity, I don't want to loose the image's rotation angle.
This is how I rotate the image.
In onclick of button 'rotate'
btn_rotate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rotateImage(true);
}
});
public void rotateImage(boolean rotate) {
RotateAnimation animation = null;
if (rotate) {
animation = new RotateAnimation(rotation, rotation + 90,
picview.getWidth() / 2, picview.getHeight() / 2);
rotation += 90;
rotation %= 360;
} else {
animation = new RotateAnimation(0, rotation,
picview.getWidth() / 2, picview.getHeight() / 2);
}
animation.setDuration(0);
animation.setFillAfter(true);
animation.setInterpolator(new LinearInterpolator());
picview.startAnimation(animation);
}
I pass the rotation angle as:
send_image.putExtra("rotation_angle", rotation);
But in the receiving activity how do I apply the rotation_angle on the Image? Can someone please guide me.
Thanks.
As a best practices do not pass the bitmap from the intent as it is heavy object.
Instead you can have few options like
1. In your application class with get and set bitmap
2. Save rotated bitmap into Sdcard in one activity and retrieve that in other activity
Hope it helps
How to move an image across the screen android?
Guys, im creating MoleMash game for My Coursework and I really need help!. I want to try to move a image (the mole) across the screen in different and random coordinates so that it can be touched by the user to get a score. I created the background which I made the image view. I have the mole, Is it another image view? or is it a Image button?
And how do I move this across to different parts of the screen for the user interact?
I would greatly appreciate your help!
For games development you need to learn how to use canvas and SurfaceView: How can I use the animation framework inside the canvas?
Using onTouch event listener you would compare the touch location with the location of your animated images...
The mole would be an image button so it could be clicked, but to make it move you would have to use animation. Keep in mind that I am a beginner in Android animation as well :). You would probably use TranslateAnimation and set the x and y in the parameters to random variables, the duration could be when a time/counter variable reaches a certain point after the game has started. This post has more information on animation: How to move an image from left to right in android.
Try this code,
declare following variables
private Random random=new Random();
private int screenwidth, screenhgt;
In onCreate():
screenwidth= getyourScreenWidth;
screenhgt=getyourscreenheight;
Pass your view to this method(In my case I animate textview.. you pass the imageview)
private void screenRandomAnimator(final TextView textView) {
final AnimatorSet mAnimatorSet = new AnimatorSet();
mAnimatorSet.playTogether(ObjectAnimator.ofFloat(textView, "x", (float) random.nextInt(screenwidth), (float) random.nextInt(screenwidth)),
ObjectAnimator.ofFloat(textView, "y", (float) random.nextInt(screenhgt), (float) random.nextInt(screenhgt)), ObjectAnimator.ofFloat(textView, "rotation", 360)
/* ObjectAnimator.ofFloat(textView, "scaleX", 1, 0.8f, 1, 1.1f, 1), ObjectAnimator.ofFloat(textView, "scaleY", 1, 0.8f, 1, 1.1f, 1)*/);
int Low = 1500;
int High = 2500;
int Result = random.nextInt(High - Low) + Low;
mAnimatorSet.setDuration(Result);
mAnimatorSet.start();
mAnimatorSet.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
mAnimatorSet.playTogether(ObjectAnimator.ofFloat(textView, "x", textView.getX(), (float) random.nextInt(screenwidth)),
ObjectAnimator.ofFloat(textView, "y", textView.getY(), (float) random.nextInt(screenhgt)));
int Low = 1500;
int High = 2500;
int Result = random.nextInt(High - Low) + Low;
mAnimatorSet.setDuration(Result);
mAnimatorSet.start();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
}
I have created a 3D flip of a view using this android tutorial
However, I have done it programmatically and I would like to do it all in xml, if possible. I am not talking about simply shrinking a view to the middle and then back out, but an actual 3D flip.
Is this possible via xml?
Here is the answer, though it only works with 3.0 and above.
1) Create a new resources folder called "animator".
2) Create a new .xml file which I will call "flipping". Use the following xml code:
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0" android:valueTo="360" android:propertyName="rotationY" >
</objectAnimator>
No, the objectAnimator tags do not start with an uppercase "O".
3) Start the animation with the following code:
ObjectAnimator anim = (ObjectAnimator) AnimatorInflater.loadAnimator(mContext, R.animator.flipping);
anim.setTarget(A View Object reference goes here i.e. ImageView);
anim.setDuration(3000);
anim.start();
I got all this from here.
Since the answers to this question are fairly dated, here is a more modern solution relying on ValueAnimators.
This solution implements a true, visually appealing 3D-flip, because it not just flips the view, but also scales it while it is flipping (this is how Apple does it).
First we set up the ValueAnimator:
mFlipAnimator = ValueAnimator.ofFloat(0f, 1f);
mFlipAnimator.addUpdateListener(new FlipListener(frontView, backView));
And the corresponding update listener:
public class FlipListener implements ValueAnimator.AnimatorUpdateListener {
private final View mFrontView;
private final View mBackView;
private boolean mFlipped;
public FlipListener(final View front, final View back) {
this.mFrontView = front;
this.mBackView = back;
this.mBackView.setVisibility(View.GONE);
}
#Override
public void onAnimationUpdate(final ValueAnimator animation) {
final float value = animation.getAnimatedFraction();
final float scaleValue = 0.625f + (1.5f * (value - 0.5f) * (value - 0.5f));
if(value <= 0.5f){
this.mFrontView.setRotationY(180 * value);
this.mFrontView.setScaleX(scaleValue);
this.mFrontView.setScaleY(scaleValue);
if(mFlipped){
setStateFlipped(false);
}
} else {
this.mBackView.setRotationY(-180 * (1f- value));
this.mBackView.setScaleX(scaleValue);
this.mBackView.setScaleY(scaleValue);
if(!mFlipped){
setStateFlipped(true);
}
}
}
private void setStateFlipped(boolean flipped) {
mFlipped = flipped;
this.mFrontView.setVisibility(flipped ? View.GONE : View.VISIBLE);
this.mBackView.setVisibility(flipped ? View.VISIBLE : View.GONE);
}
}
That's it!
After this setup you can flip the views by calling
mFlipAnimator.start();
and reverse the flip by calling
mFlipAnimator.reverse();
If you want to check if the view is flipped, implement and call this function:
private boolean isFlipped() {
return mFlipAnimator.getAnimatedFraction() == 1;
}
You can also check if the view is currently flipping by implementing this method:
private boolean isFlipping() {
final float currentValue = mFlipAnimator.getAnimatedFraction();
return (currentValue < 1 && currentValue > 0);
}
You can combine the above functions to implement a nice function to toggle the flip, depending on if it is flipped or not:
private void toggleFlip() {
if(isFlipped()){
mFlipAnimator.reverse();
} else {
mFlipAnimator.start();
}
}
That's it! Simple and easy. Enjoy!
I have created a simple program for creating flip of view like :
In Activity you have to create this method, for adding flip_rotation in view.
private void applyRotation(View view)
{
final Flip3dAnimation rotation = new Flip3dAnimation(view);
rotation.applyPropertiesInRotation();
view.startAnimation(rotation);
}
for this, you have to copy main class used to provide flip_rotation.
import android.graphics.Camera;
import android.graphics.Matrix;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class Flip3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private Camera mCamera;
public Flip3dAnimation(View view) {
mFromDegrees = 0;
mToDegrees = 720;
mCenterX = view.getWidth() / 2.0f;
mCenterY = view.getHeight() / 2.0f;
}
#Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
public void applyPropertiesInRotation()
{
this.setDuration(2000);
this.setFillAfter(true);
this.setInterpolator(new AccelerateInterpolator());
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees
+ ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
Log.e("Degree",""+degrees) ;
Log.e("centerX",""+centerX) ;
Log.e("centerY",""+centerY) ;
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
The tutorial or the link by om252345 don't produce believable 3D flips. A simple rotation on the y-axis isn't what's done in iOS. The zoom effect is also needed to create that nice flip feel. For that, take a look at this example.
There is also a video here.
One of the better solution to flip the image with out use of the resource animation , is as follow:-
ObjectAnimator animation = ObjectAnimator.ofFloat(YOUR_IMAGEVIEW, "rotationY", 0.0f, 360f); // HERE 360 IS THE ANGLE OF ROTATE, YOU CAN USE 90, 180 IN PLACE OF IT, ACCORDING TO YOURS REQUIREMENT
animation.setDuration(500); // HERE 500 IS THE DURATION OF THE ANIMATION, YOU CAN INCREASE OR DECREASE ACCORDING TO YOURS REQUIREMENT
animation.setInterpolator(new AccelerateDecelerateInterpolator());
animation.start();
The simplest way to do it is using ViewPropertyAnimator
mImageView.animate().rotationY(360f);
Using the fluent interface you can build more complex and exciting animation.
E.g. you can enable hardware acceleration just call withLayer() method(API 16). More here
If you want to figure out how to create 3d flick animation, please follow here and here
I implemended my own solution only for a research. It includes: cancelation, accelleration, support API >= 15 and is based on Property Animation.
The entire animation includes 4 parts, 2 for each side.
Every objectAnimator has a listener that defines current animation index and represents an image in the onAnimationStart and current play time value in the onAnimationCancel.
It looks like
mQuarterAnim1.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationStart(Animator animation) {
mQuarterCurrentAnimStartIndex = QUARTER_ANIM_INDEX_1;
mImageView.setImageResource(mResIdFrontCard);
}
#Override
public void onAnimationCancel(Animator animation) {
mQuarterCurrentAnimPlayTime = ((ObjectAnimator) animation).getCurrentPlayTime();
}
});
For start set call
mAnimatorSet.play(mQuarterAnim1).before(mQuarterAnim2)
If AnimatorSet was canceled we can calculate delta and run the reverse animation relying on the current index animation and the current play time value.
long degreeDelta = mQuarterCurrentAnimPlayTime * QUARTER_ROTATE / QUARTER_ANIM_DURATION;
if (mQuarterCurrentAnimStartIndex == QUARTER_ANIM_INDEX_1) {
mQuarterAnim4.setFloatValues(degreeDelta, QUARTER_FROM_1);
mQuarterAnim4.setDuration(mQuarterCurrentAnimPlayTime);
mAnimatorSet.play(mQuarterAnim4);
}
A full code snippet you can find here
Just put the view which you're going to animate it in place of viewToFlip.
ObjectAnimator flip = ObjectAnimator.ofFloat(viewToFlip, "rotationY", 0f, 360f); // or rotationX
flip.setDuration(2000); // 2 seconds
flip.start();
Adding to A. Steenbergen's great answer. When flipping the same view (updating a TextView for example) I removed the View.Visibility change in the constructor in order to keep the transition smoother.
public FlipListener(final View front, final View back) {
this.mFrontView = front;
this.mBackView = back;
}