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.
I am developing a game where a user needs to tap on the image in ImageView to rotate it. On each tap image rotates by 90 degrees in clockwise direction.
But image is taking time to rotate from old to new position. This is hampering the gameplay experience. I have used the following:
protected void onCreate(Bundle savedInstanceState)
{
...
...
imgview = (ImageView)findViewById(R.id.imageView1);
imgview.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap myImg = getBitmapFromDrawable(imgview.getDrawable());
Bitmap rotated = Bitmap.createBitmap(myImg,0,0,myImg.getWidth(),myImg.getHeight(),matrix,true);
imgview.setImageBitmap(rotated);
}
});
I want to know is there any other way to rotate the image
without creating any delay in rotation.
I also tried to do it once and couldn't find any other solution but using animation. Here how I'd do.
private void rotate(float degree) {
final RotateAnimation rotateAnim = new RotateAnimation(0.0f, degree,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
rotateAnim.setDuration(0);
rotateAnim.setFillAfter(true);
imgview.startAnimation(rotateAnim);
}
You don't need to rotate the object, rotating the view should be enough.
If you are aiming API>=11 you can always do this.
mImageView.setRotation(angle);
Cheers.
Short method
View.animate().rotation(90).setDuration(0);
did you try to use a custom view extending imageview and rotating the image in a background thread?
I am using the following code to rotate a image in ImageView by an angle. Is there any simpler and less complex method available.
ImageView iv = (ImageView)findViewById(imageviewid);
TextView tv = (TextView)findViewById(txtViewsid);
Matrix mat = new Matrix();
Bitmap bMap = BitmapFactory.decodeResource(getResources(),imageid);
mat.postRotate(Integer.parseInt(degree));===>angle to be rotated
Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0,bMap.getWidth(),bMap.getHeight(), mat, true);
iv.setImageBitmap(bMapRotate);
mImageView.setRotation(angle) with API>=11
Another simple way to rotate an ImageView:
UPDATE:
Required imports:
import android.graphics.Matrix;
import android.widget.ImageView;
Code: (Assuming imageView, angle, pivotX & pivotY are already defined)
Matrix matrix = new Matrix();
imageView.setScaleType(ImageView.ScaleType.MATRIX); //required
matrix.postRotate((float) angle, pivotX, pivotY);
imageView.setImageMatrix(matrix);
This method does not require creating a new bitmap each time.
NOTE: To rotate an ImageView on ontouch at runtime you can
set onTouchListener on ImageView & rotate it by adding last two
lines(i.e. postRotate matrix & set it on imageView) in above code
section in your touch listener ACTION_MOVE part.
If you're supporting API 11 or higher, you can just use the following XML attribute:
android:rotation="90"
It might not display correctly in Android Studio xml preview, but it works as expected.
There are two ways to do that:
1 Using Matrix to create a new bitmap:
imageView = (ImageView) findViewById(R.id.imageView);
Bitmap myImg = BitmapFactory.decodeResource(getResources(), R.drawable.image);
Matrix matrix = new Matrix();
matrix.postRotate(30);
Bitmap rotated = Bitmap.createBitmap(myImg, 0, 0, myImg.getWidth(), myImg.getHeight(),
matrix, true);
imageView.setImageBitmap(rotated);
2 use RotateAnimation on the View you want to Rotate, and make sure the Animation set to fillAfter=true, duration=0, and fromDegrees=toDgrees
<?xml version="1.0" encoding="utf-8"?>
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="45"
android:toDegrees="45"
android:pivotX="50%"
android:pivotY="50%"
android:duration="0"
android:startOffset="0"
/>
and Inflate the Animation in code:
Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotation);
myView.startAnimation(rotation);
I know this is insanely late, but it was helpful for me so it may help others.
As of API 11, you can set the absolute rotation of an ImageView programmatically by using the imageView.setRotation(angleInDegrees); method.
By absolute, I mean you can repeatedly call this function without having to keep track of the current rotation. Meaning, if I rotate by passing 15F to the setRotation() method, and then call setRotation() again with 30F, the image's rotation with be 30 degrees, not 45 degrees.
Note: This actually works for any subclass of the View object, not just ImageView.
For Kotlin,
mImageView.rotation = 90f //angle in float
This will rotate the imageView rather than rotating the image
Also, though its a method in View class. So you can pretty much rotate any view using it.
Can also be done this way:-
imageView.animate().rotation(180).start();
got from here.
Rotate an image in android with delay:
imgSplash.animate().rotationBy(360f).setDuration(3000).setInterpolator(new LinearInterpolator()).start();
This is my implementation of RotatableImageView. Usage is very easy: just copy attrs.xml and RotatableImageView.java into your project and add RotatableImageView to your layout. Set desired rotation angle using example:angle parameter.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:example="http://schemas.android.com/apk/res/com.example"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.example.views.RotatableImageView
android:id="#+id/layout_example_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="#drawable/ic_layout_arrow"
example:angle="180" />
</FrameLayout>
If you have some problems with displaying image, try change code in RotatableImageView.onDraw() method or use draw() method instead.
Also, if you want to rotate an ImageView by 180 degrees vertically or horizontally, you can use scaleY or scaleX properties and set them to -1f. Here is a Kotlin example:
imageView.scaleY = -1f
imageView.scaleX = -1f
1f value is used to return an ImageView to its normal state:
imageView.scaleY = 1f
imageView.scaleX = 1f
I have a solution to this.
Actually it is a solution to a problem that arises after rotation(Rectangular image doesn't fit ImagView)
but it covers your problem too..
Although this Solution has Animation for better or for worse
int h,w;
Boolean safe=true;
Getting the parameters of imageView is not possible at initialisation of activity
To do so please refer to this solution
OR set the dimensions at onClick of a Button Like this
rotateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(imageView.getRotation()/90%2==0){
h=imageView.getHeight();
w=imageView.getWidth();
}
.
.//Insert the code Snippet below here
}
And the code to be run when we want to rotate ImageView
if(safe)
imageView.animate().rotationBy(90).scaleX(imageView.getRotation()/90%2==0?(w*1.0f/h):1).scaleY(imageView.getRotation()/90%2==0?(w*1.0f/h):1).setDuration(2000).setInterpolator(new LinearInterpolator()).setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
safe=false;
}
#Override
public void onAnimationEnd(Animator animation) {
safe=true;
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
}).start();
}
});
This solution is sufficient for the Problem above.Although it will shrink the imageView even if it is not necessary(when height is smaller than Width).If it bothers you,you can add another ternary operator inside scaleX/scaleY.
I think the best method :)
int angle = 0;
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
angle = angle + 90;
imageView.setRotation(angle);
}
});
You can simply use rotation atribute of ImageView
Below is the attribute from ImageView with details from Android source
<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />
Sadly, I don't think there is. The Matrix class is responsible for all image manipulations, whether it's rotating, shrinking/growing, skewing, etc.
http://developer.android.com/reference/android/graphics/Matrix.html
My apologies, but I can't think of an alternative. Maybe someone else might be able to, but the times I've had to manipulate an image I've used a Matrix.
Best of luck!
try this on a custom view
public class DrawView extends View {
public DrawView(Context context,AttributeSet attributeSet){
super(context, attributeSet);
}
#Override
public void onDraw(Canvas canvas) {
/*Canvas c=new Canvas(BitmapFactory.decodeResource(getResources(), R.drawable.new_minute1) );
c.rotate(45);*/
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.new_minute1), 0, 0, null);
canvas.rotate(45);
}
}
here's a nice solution for putting a rotated drawable for an imageView:
Drawable getRotateDrawable(final Bitmap b, final float angle) {
final BitmapDrawable drawable = new BitmapDrawable(getResources(), b) {
#Override
public void draw(final Canvas canvas) {
canvas.save();
canvas.rotate(angle, b.getWidth() / 2, b.getHeight() / 2);
super.draw(canvas);
canvas.restore();
}
};
return drawable;
}
usage:
Bitmap b=...
float angle=...
final Drawable rotatedDrawable = getRotateDrawable(b,angle);
root.setImageDrawable(rotatedDrawable);
another alternative:
private Drawable getRotateDrawable(final Drawable d, final float angle) {
final Drawable[] arD = { d };
return new LayerDrawable(arD) {
#Override
public void draw(final Canvas canvas) {
canvas.save();
canvas.rotate(angle, d.getBounds().width() / 2, d.getBounds().height() / 2);
super.draw(canvas);
canvas.restore();
}
};
}
also, if you wish to rotate the bitmap, but afraid of OOM, you can use an NDK solution i've made here
If you only want to rotate the view visually you can use:
iv.setRotation(float)
if u want to rotate an image by 180 degrees then put these two value in imageview tag:-
android:scaleX="-1"
android:scaleY="-1"
Explanation:- scaleX = 1 and scaleY = 1 repesent it's normal state but if we put -1 on scaleX/scaleY property then it will be rotated by 180 degrees
Another possible solution is to create your own custom Image view(say RotateableImageView extends ImageView )...and override the onDraw() to rotate either the canvas/bitmaps before redering on to the canvas.Don't forget to restore the canvas back.
But if you are going to rotate only a single instance of image view,your solution should be good enough.
without matrix and animated:
{
img_view = (ImageView) findViewById(R.id.imageView);
rotate = new RotateAnimation(0 ,300);
rotate.setDuration(500);
img_view.startAnimation(rotate);
}
just write this in your onactivityResult
Bitmap yourSelectedImage= BitmapFactory.decodeFile(filePath);
Matrix mat = new Matrix();
mat.postRotate((270)); //degree how much you rotate i rotate 270
Bitmap bMapRotate=Bitmap.createBitmap(yourSelectedImage, 0,0,yourSelectedImage.getWidth(),yourSelectedImage.getHeight(), mat, true);
image.setImageBitmap(bMapRotate);
Drawable d=new BitmapDrawable(yourSelectedImage);
image.setBackground(d);
Try this code 100% working;
On rotate button click write this code:
#Override
public void onClick(View view) {
if(bitmap==null){
Toast.makeText(getApplicationContext(), "Image photo is not yet set", Toast.LENGTH_LONG).show();
}
else {
Matrix matrix = new Matrix();
ivImageProduct.setScaleType(ImageView.ScaleType.MATRIX); //required
matrix.postRotate(90,ivImageProduct.getDrawable().getBounds().width()/2,ivImageProduct.getDrawable().getBounds().height()/2);
Bitmap bmp=Bitmap.createBitmap(bitmap, 0, 0,bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
bitmap=bmp;
ivImageProduct.setImageBitmap(bitmap);
}
}
Rather than convert image to bitmap and then rotate it try to rotate direct image view like below code.
ImageView myImageView = (ImageView)findViewById(R.id.my_imageview);
AnimationSet animSet = new AnimationSet(true);
animSet.setInterpolator(new DecelerateInterpolator());
animSet.setFillAfter(true);
animSet.setFillEnabled(true);
final RotateAnimation animRotate = new RotateAnimation(0.0f, -90.0f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animRotate.setDuration(1500);
animRotate.setFillAfter(true);
animSet.addAnimation(animRotate);
myImageView.startAnimation(animSet);
Follow the below answer for continuous rotation of an imageview
int i=0;
If rotate button clicked
imageView.setRotation(i+90);
i=i+90;
Matrix matrix = new Matrix();
imageView.setScaleType(ImageView.ScaleType.MATRIX); //required
matrix.postRotate((float) 20, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
imageView.setImageMatrix(matrix);
how to use?
public class MainActivity extends AppCompatActivity {
int view = R.layout.activity_main;
TextView textChanger;
ImageView imageView;
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(view);
textChanger = findViewById(R.id.textChanger);
imageView=findViewById(R.id.imageView);
textChanger.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
roateImage(imageView);
}
});
}
private void roateImage(ImageView imageView) {
Matrix matrix = new Matrix();
imageView.setScaleType(ImageView.ScaleType.MATRIX); //required
matrix.postRotate((float) 20, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
imageView.setImageMatrix(matrix);
}
}
It is too late for the answer, someone may found this useful, I came across a situation where I need to animate the rotation og ImageView by some angle on first ClickListener event, and then on the 2nd ClickListener event, need to rotate back the image to the original angle. this is how this magic happened
fun rotateAnim(imageView: ImageView,angle : Float){
imageView.isEnabled = false
Log.i(TAG, "onCreate: ${imageView.rotation}")
val rotation = imageView.animate().rotationBy(angle)
rotation.interpolator = FastOutSlowInInterpolator()
rotation.startDelay = 200
rotation.setListener(object : Animator.AnimatorListener{
override fun onAnimationEnd(animation: Animator?) {
imageView.isEnabled = true
}
override fun onAnimationStart(animation: Animator?) {}
override fun onAnimationCancel(animation: Animator?) {}
override fun onAnimationRepeat(animation: Animator?) {}
})
rotation.start()
}
and implementation is like
holder.itemView.setOnClickListener {
val rotation = imageView.rotation
if(rotation == 180F){
rotateAnim(imageView,90F)
}else{
rotateAnim(imageView,-90F)
}
}
Using Kotlin:
imageView.rotation = degrees.toFloat()
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 want to rotate an imageview from 30 degrees on each click on a button.
On the first clic, i can set the animation properly but i can't succeed to update the imageview position after the animation. When i clicked again on the button, the animation start from the original position of the imageview and not from the final position after the first animation.
Here is my code :
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
turnImg = (ImageView) findViewById(R.id.imageViewturnImg );
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.imgTurn);
// Getting width & height of the given image.
int w = bmp.getWidth();
int h = bmp.getHeight();
turnImg .setImageBitmap(bmp);
Button buttonok = (Button) findViewById(R.id.buttonok);
buttonok.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
turn();
}
});
}
public void turn()
{
float degrees = 30;
RotateAnimation anim = new RotateAnimation(0, degrees,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
anim.setInterpolator(new LinearInterpolator());
anim.setDuration(300);
anim.setFillEnabled(true);
anim.setFillAfter(true);
anim.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation arg0) {
Matrix mat = turnImg.getImageMatrix();
mat.postRotate(30,turnImg.getWidth()/2, turnImg.getHeight()/2);
turnImg.setScaleType(ScaleType.MATRIX);
turnImg.setImageMatrix(mat);
}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationStart(Animation animation) {}
});
turnImg.startAnimation(anim);
}
I think the problem came from the way i actualize the position in the onAnimationEnd().
ps : sorry for my bad english...
The problem is that your animation is not affecting the same object as your matrix rotation. That is, you are animating the rotation of the ImageView object, but then you are setting the rotation of the image that is within that ImageView object. So, for example, the first time you rotate it, the ImageView rotates from 0 to 30 degrees, and then remains at a rotation of 30 degrees due to the call to setFillAfter(true). Then the onAnimationEnd() handler runs, which rotates the internal image by 30 degrees. This effectively jumps the image to a rotation of 60 degrees, as seen by the user (30 for the View, 30 for the bitmap). Then the next time the animation runs, it rotates the view from 0 to 30 degrees, with the internal image still at its rotation of 30 degrees. This makes it look to the user like it's rotating from 30 to 60 degrees. Then you apply another rotation on the internal image when that animation finishes, ending up with the image rotated to 60 degrees and the view rotated (again) to 30 degrees, so the image is now visually rotated to 90 degrees.
And so on.
There are different ways to handle this problem, but one simple way is to avoid affecting the two different objects - just work with the ImageView. Instead of rotating from 0 to 30 each time, rotate from whatever the current rotation is to that value plus 30 degrees. You can remove the onAnimationEnd() handler, because you will no longer need to rotate the image inside the view.
The resulting code for turn() is much simpler:
public void turn()
{
RotateAnimation anim = new RotateAnimation(currentRotation, currentRotation + 30,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
currentRotation = (currentRotation + 30) % 360;
anim.setInterpolator(new LinearInterpolator());
anim.setDuration(1000);
anim.setFillEnabled(true);
anim.setFillAfter(true);
turnImg.startAnimation(anim);
}
This code assumes an instance variable of currentRotation, which is used to track the last degrees the view was rotated to.
Its a bit more involved if you allow the user to click mid-animation, but not too difficult.
By the way, this is much simpler in the animation system in 3.0; there is now a 'rotation' property on View, and you can run an animation on that property and it can track its own current value. But the approach above should work for older releases.