I want to have an animation with various steps that do moves (translations) and rotations like "straight on, turn left, straight on, ...." of a car.
I am able to do this in an AnimationSet, but fail at rotating around the center of my car image with the "RELATIVE_TO_SELF" setting. I know about
Animation a = new RotateAnimation(0,90,Animation.RELATIVE_TO_SELF,0.5f,... )
for this purpose. Still the rotation occurs around the upper left corner of the screen (or canvas?).
Currently I am solving this by manually keeping track of the position after each animation step, but this is suboptimal.
I suspect that my initial layout setup is bogus:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<FrameLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<!-- view that draws some background -->
<de.bsd.turtlecar.SampleView android:id="#+id/graph_view"
android:layout_height="350px"
android:layout_width="fill_parent"
android:visibility="invisible"
/>
<!-- the car -->
<ImageView android:id="#+id/car_view"
android:src="#drawable/turtle_car"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:visibility="invisible"/>
</FrameLayout>
<Button ... onClick="run" ... />
</LinearLayout>
This shows the car in the upper left corner (should show up in a different place -- basically where the animation later starts. And it should be move later).
In my code that is triggered through the run button I do:
ImageView carView = (ImageView) findViewById(R.id.car_view);
print(carView);
AnimationSet animationSet = new AnimationSet(true);
TranslateAnimation a = new TranslateAnimation(
Animation.ABSOLUTE,200, Animation.ABSOLUTE,200,
Animation.ABSOLUTE,200, Animation.ABSOLUTE,200);
a.setDuration(1000);
animationSet.addAnimation(a);
RotateAnimation r = new RotateAnimation(0f, -90f,200,200); // HERE
r.setStartOffset(1000);
r.setDuration(1000);
animationSet.addAnimation(r);
...
So at the point with here, the rotation works, but I have to keep track. if I rotate RELATIVE_TO_SELF, the rotation happens around (0,0) of the screen.
Additional question: what can I do in order to keep the car on screen after the animation has finished?
Or am I completely on the wrong track?
Try adding setFillAfter(true) to your Animations. That will certainly keep the car in its final place and it may solve your rotation point problems too
TranslateAnimation a = new TranslateAnimation(
Animation.ABSOLUTE,200, Animation.ABSOLUTE,200,
Animation.ABSOLUTE,200, Animation.ABSOLUTE,200);
a.setDuration(1000);
a.setFillAfter(true); //HERE
animationSet.addAnimation(a);
RotateAnimation r = new RotateAnimation(0f, -90f,200,200); // HERE
r.setStartOffset(1000);
r.setDuration(1000);
r.setFillAfter(true); //HERE
animationSet.addAnimation(r);
...
Related
This is my xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="#+id/bounceBallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Bounce Ball" />
<ImageView
android:id="#+id/bounceBallImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#id/bounceBallButton"
android:src="#drawable/ball" />
</RelativeLayout>
and this is my animation code to bounce my imageview:
Button bounceBallButton = (Button) findViewById(R.id.bounceBallButton);
final ImageView bounceBallImage = (ImageView) findViewById(R.id.bounceBallImage);
bounceBallImage.clearAnimation();
TranslateAnimation transAnim = new TranslateAnimation(0, 0, 0, getDisplayHeight());
transAnim.setStartOffset(500);
transAnim.setDuration(3000);
transAnim.setFillAfter(true);
transAnim.setInterpolator(new BounceInterpolator());
bounceBallImage.startAnimation(transAnim);
My problem is that the animation takes my imageview below my screen. I want it to hit at the bottom of my screen and bounce and not go below it.
You animate Y position to getDisplayHeight(). Which means, that you tell the framework:
animate this view's top Y position to the screen's bottom.
And framework does exactly what you say.
What you want to do is to animate to getDisplayHeight() - bounceBallImage.getHeight(). But as soon as you do that, you'll find out, that it gives you the same result. That's because getHeight() returns 0, and that's because your view's hasn't been drawn, hence it has not height.
See here how to know the height of the view as soon as it is measured. You'd be using getMeasuredHeight() instead of getHeight().
I'm trying to build an app where if you click on a profile pic, the pic will expand to the centre of the screen with the background of the app dimmed (similar to what you would experience if you click on a profile pic on whatsapp). Clicking anywhere on the dimmed area would reverse the animation and the profile pic will reset back into the original position.
I have the following xml layout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:id="#+id/profilepage"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/brown_400"
android:id="#+id/profileBox">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/profilepic"
android:src="#drawable/ic_person_black_24dp"
/>
<TextView
android:layout_toRightOf="#+id/profilepic"
android:layout_alignTop="#+id/profilepic"
android:textSize="20sp"
android:textColor="#color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/profileName"
tools:text="Johnny Appleseed"/>
</RelativeLayout>
...other layout stuff like buttons etc to be put here...
</LinearLayout>
I want to click on the little man above and it should translate and scale to the middle of the screen.
I found some code here Translate and Scale animation in parallel which serve my purpose:
private void moveViewToScreenCenter( final View view ){
view.bringToFront(); //brings the view to the front
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics( dm );
int originalPos[] = new int[2];
view.getLocationOnScreen( originalPos );
int xDelta = (dm.widthPixels - view.getMeasuredWidth() - originalPos[0])/2;
int yDelta = (dm.heightPixels - view.getMeasuredHeight() - originalPos[1])/2;
AnimationSet animSet = new AnimationSet(true);
animSet.setFillAfter(true);
animSet.setDuration(1000);
animSet.setInterpolator(new BounceInterpolator());
TranslateAnimation translate = new TranslateAnimation( 0, xDelta , 0, yDelta);
animSet.addAnimation(translate);
ScaleAnimation scale = new ScaleAnimation(1f, 2f, 1f, 2f, ScaleAnimation.RELATIVE_TO_PARENT, .5f, ScaleAnimation.RELATIVE_TO_PARENT, .5f);
animSet.addAnimation(scale);
view.startAnimation(animSet);
}
However, the code would only scale relative to the parent of the profile pic ImageView, which in my case is the RelativeLayout (#+id/profileBox) and not the parent's parent (#+id/profilepage) which is what I want it to do.
Also, the code: view.bringToFront(); doesn't bring the profile picture to the front of the LinearLayout (profilepage) to scale and translate, but instead brings it to the front of the RelativeLayout (profileBox).
How can I bring it to the front of profilepage and scale it appropriately so that it will be centered in my app screen?
I managed to find an answer to first question: Android View Disappearing When Go Outside Of Parent
I needed to set this for profileBox:
android:clipChildren="false"
android:clipToPadding="false"
And this for profilepage:
android:clipChildren="false"
But I am starting to realise that this might not be the correct strategy for what I want to do as I want the background to be dimmed when the profile pic is translating / scaling and the buttons behind the profile picture not to be accessible as the activity is in a Paused state.
My code above will only translate / scale the image without pausing the activity below so clicking on 'Log Out' will log out the user.
I try to develop an application with a left/right animation on the background on the first screen.
For example, this application have an image in background and this image move from left to right. It's exactly what I want to do.
I try with this code :
ImageView imageViewBackground = (ImageView)findViewById(R.id.imageViewBackground);
Animation animation = new TranslateAnimation(0.0f, 200.0f, 0.0f, 0.0f);
animation.setDuration(5000);
imageViewBackground.startAnimation(animation);
and
<ImageView android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/imageViewBackground"
android:src="#drawable/background"
android:scaleType="centerCrop" />
But the imageView with this scaleType are cropped and we can't see the content of the imageView entirely current the animation.
You can use my SlideImageView library from the GitHub. It gives you what you want.
i can't change the position of the login button.Because when i try, it can't be moved from the original position. I' ve set the android:layout_gravity and android:gravity but i want it in a specific position.
how i can set the coordinates (x,y) of the image?
this is the login_fragment.xml
LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
<ImageView
android:id="#+id/login"
android:layout_width="400px"
android:layout_height="100px"
android:src="#drawable/login_button" />
You cant do it within the xml itself, you need to create an instance of that ImageView in your activity and call its setX() or setY() method to set the coordinates.
Beware that every screen has different number of pixels, you might have different result on different devices.
Sample:
ImageView s = (ImageView) findViewById(R.id.your_id);
s.setY(number);
s.setX(number);
TranslateAnimation animation = new TranslateAnimation(0.0f, 50.0f, 0.0f, 0.0f);
animation.setDuration(700);
animation.setRepeatCount(5);
animation.setRepeatMode(2);
animation.setFillAfter(true);
image.startAnimation(animation);
I have a vertical linearlayout with three clickable imageviews within the linearlayout. When i rotate the linearlayout by 90 degrees using simple animation the problem arises. The imageviews are rotated correctly but the onclick events for the imageviews are not rotated along with the linearlayout and remain in the original position as before the animation.
Below is my main java code
westplayer = (LinearLayout) findViewById(R.id.linearLayout_west);
// Create an animation instance
Animation an = new RotateAnimation(0.0f, 180.0f, 32, 180);
// Set the animation's parameters
an.setDuration(0); // duration in ms
an.setRepeatCount(0); // -1 = infinite repeated
an.setRepeatMode(Animation.REVERSE); // reverses each repeat
an.setFillAfter(true); // keep rotation after animation
// Apply animation to linearlayout
westplayer.setAnimation(an);
The code above handles the animation part. The code below follows the animation and is supoosed to update the layout positions but is not working for me.
// Update Layout
int top=westplayer.getTop();
int bottom=westplayer.getBottom();
int left=westplayer.getLeft();
int right=westplayer.getRight();
westplayer.layout(left, top , right, bottom );
The xml is as follows:
<LinearLayout
android:id="#+id/linearLayout_west"
android:layout_width="42dp"
android:layout_height="250dp"
android:layout_alignParentLeft="true"
android:layout_below="#+id/linearLayout_north"
android:duplicateParentState="false"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageViewW1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/spades_14"
/>
<ImageView
android:id="#+id/imageViewW2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/spades_14"
android:layout_marginTop="-15dp"
/>
<ImageView
android:id="#+id/imageViewW3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/spades_14"
android:layout_marginTop="-15dp"
/>
</LinearLayout>
I have got the update layout code from this and also found another solution that i have also tried this and still no positive results. I need this to work for API 10. Any help is much appreciated
Yes, you got the expected result.
Since Animation in android only try to apply a transformation matrix on the bitmap of view, it doesn't change the position and size of view.
So after your animation, although you setFillAfter(true) to let the view looks rotated, but in fact the view are still in the same place and doesn't move a little bit.
The problem you face, is because you use a Tween Animation. The View will rotate and only the visible part will move. But the positions of the ImageView will remain the same like defined in the layout. That's why the clickable area stays the same.
To redefine the position, according to the animation you will have to use a Property Animation, like a ObjectAnimator or a ValueAnimator. With this the propertys defined in xml will be updated. Now the clickable areas move along with the views.