Delays within the Animation (TranslateAnimation) - android

Is there a way to have the Animation pause for a half a second?
I am trying to make an infinite animation using the TranslateAnimation API. So, I use the RepeatCount as Infinite. I also noticed that there's a setStartOffset(...) method that covers the case when I'd like to have a delay in starting the animation. However, I can't find a way to have a delay before each 'restart'. Since animation is gonna happen infinite amount of times, every time the animation restarts I need to put a delay in.
Any ideas?
Thanks!!

Here is an example:
First the layout (main.xml) with an image we would like to animate:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</LinearLayout>
Next one is the animation. Placed in res/anim and is called anim_img.xml. The file contains the translation animation with android:startOffset="500" (in millisec). This will set the offset, which is used every time animation starts:
<?xml version="1.0" encoding="utf-8"?>
<set>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXDelta="0%"
android:fromYDelta="0%"
android:toXDelta="0%"
android:toYDelta="100%"
android:zAdjustment="top"
android:repeatCount="infinite"
android:startOffset="500"/>
</set>
And last but not least - the activity. Which starts the animation:
public class StackOverflowActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView iv_icon = (ImageView) findViewById(R.id.imageView1);
Animation a = AnimationUtils.loadAnimation(this, R.anim.anim_img);
a.setFillAfter(true);
a.reset();
iv_icon.startAnimation(a);
}
}

To achieve a pause of x milliseconds between each restart:
myAnimation.setAnimationListener(new AnimationListener(){
#Override
public void onAnimationStart(Animation arg0) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
myAnimation.setStartOffset(x);
}
});

myanimation.setStartDelay(int);

Related

Animate view in relative layout to align parent top

I have a relative layout (let's call it A), inside a scroll view, inside a relative layout (we will call this layout B)
What I'm trying to do is remove a child from A, insert it into B and align it to the parent top (right below the action bar).
I've been trying to animate this slide up, and back down to it's original position without any luck.
Any idea how can I perform this animation?
A very late reply, but here's how I managed this:
center_to_top_center.xml (located in res/anim/)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1000"
android:fillAfter="true"
android:fromXDelta="0%p"
android:fromYDelta="00%p"
android:toXDelta="00%p"
android:toYDelta="-40%p" />
</set>
HomeActivity.java
public class HomeActivity extends FragmentActivity {
#InjectView(R.id.imageView2)
ImageView mImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_home, false);
beginLogoAnimation();
}
private void beginLogoAnimation(){
Animation translateAnim= AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.center_to_top_center);
translateAnim.setFillAfter(true);
translateAnim.setFillEnabled(true);
translateAnim.setFillBefore(false);
translateAnim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
mImageView.startAnimation(translateAnim);
}
}
activity_home.xml
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView2"
android:layout_centerInParent="true"
android:layout_marginTop="15dp"
android:layout_centerHorizontal="true"
android:src="#drawable/logo"
/>
Since you are Animating Layout Changes Try adding this to your layout block:
android:animateLayoutChanges="true"
Source: http://developer.android.com/guide/topics/graphics/prop-animation.html#layout

Send signal to previous activity without finish

Is there any way that foreground activity send some signal (such as callback) to the previous activity without finishing foreground activity?
I am implementing activity transition on my own. Once user clicks one of images on activity A, activity B is launched with the bitmap, position and dimension of the image. The original image from A is hidden, and activity B animates imageview with the bitmap at the exact location in the exact size. So it seems the image from A moves. Simple.
But the problem is, there is very small time gap between hiding image from A, and start drawing image at B, so there is some flickering. Although I am currently hiding image from A after 100ms, I don't think that's good solution overall.
Is there any way that activity B can notify activity A just right before animation starts in order to hide original image properly?
Simple, do not use different activities for this. Instead use animations.
Here's a simple example to translate and scale an ImageView:
MainActivity.java:
public class MainActivity extends ActionBarActivity {
private ImageView ivImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivImage = (ImageView) findViewById(R.id.ivImage);
ivImage.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.background));
ivImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animate();
}
});
}
private void animate() {
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.bitmap_movement);
ivImage.startAnimation(animation);
}
}
bitmap_movement.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fillEnabled="true">
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="0.5"
android:toYScale="0.5" />
<translate
android:fromXDelta="0"
android:toXDelta="240" />
</set>
Layout main_activity.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ImageView
android:id="#+id/ivImage"
android:layout_width="40dp"
android:layout_height="40dp" />
</RelativeLayout>

Android detects clicks when it shouldn't

I have an image button and associated click handler.
When I animate button (using translate animation) the button, obviously, changes it's position on screen.
But there is a problem: Android detects clicks when I touch initial button location and not the current.
How can I make Android respect actual location of the button?
fragment_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:id="#+id/addButton"
android:src="#android:drawable/ic_input_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="plusButtonClick"/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends ActionBarActivity
{
public void plusButtonClick(View v)
{
Toast.makeText(this, "Clicked!", Toast.LENGTH_SHORT).show();
animateButton(R.id.addButton, R.anim.anim_move);
}
private void animateButton(int buttonId, int animationId)
{
View button = findViewById(buttonId);
AnimationSet animationSet = (AnimationSet)AnimationUtils.loadAnimation(this, animationId);
animationSet.setAnimationListener(getStartingButtonsListener(button));
button.setVisibility(View.VISIBLE);
button.startAnimation(animationSet);
}
private Animation.AnimationListener getStartingButtonsListener(final View v)
{
return new Animation.AnimationListener()
{
#Override
public void onAnimationEnd(Animation arg0)
{
v.setVisibility(View.GONE);
}
};
}
}
anim_move.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true"
android:fillAfter="true"
android:duration="1000">
<translate
android:fromXDelta="0"
android:toXDelta="180"
android:fromYDelta="0"
android:toYDelta="0"/>
</set>
I had a similar problem here : Button moves to different part of screen but can only press it at its initial spot?
The animation is animating the pixels, not the touch zones of a widget.
You need to animate the properties as well : https://developer.android.com/guide/topics/graphics/prop-animation.html
The translate animation doesn't actually move your object, it just moves the image of it. You should reposition your button yourself at the end of the animation by editing its LayoutParams
Use onTouchEvent for your button. Moreover, give this onTouch implementation through java file, but not with the XML layout file. This is far better than using onClick event.
See this : Triggering event when Button is pressed down in Android

android imageview with multiple image fade in fade out animation

its my first time to ask question here...
im hoping that somebody could help me....
i want to animate multiple images that animates as fade in and fade out. i was able to animate one imageview but what i need is once the first imageview fade out, the second imageview must fade in and so on...
it should loop once the application is opened. thanks
here is how i call the animation in my java onCreate(),
final ImageView image = (ImageView)findViewById(R.id.bsc);
final Animation animationFadeIn = AnimationUtils.loadAnimation(this, R.anim.fadein);
image.startAnimation(animationFadeIn);
final Animation animationFadeOut = AnimationUtils.loadAnimation(this, R.anim.fadeout);
image.startAnimation(animationFadeOut);
fade in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<alpha
android:fromAlpha="0.1"
android:toAlpha="1.0"
android:duration="2000"
/>
</set>
fade out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.1"
android:duration="2000"
/>
</set>
Try using AnimationListener.
final ImageView image = (ImageView)findViewById(R.id.bsc);
final Animation animationFadeIn = AnimationUtils.loadAnimation(this, R.anim.fadein);
final Animation animationFadeOut = AnimationUtils.loadAnimation(this, R.anim.fadeout);
AnimationListener animListener = new AnimationListener(){
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
image.setImageResource(R.drawable.hsc);
image.startAnimation(animationFadeIn);
}
};
image.startAnimation(animationFadeOut);
animationFadeOut.setAnimationListener(animListener);
If you want to loop, then put another listener on animationFadeIn also. This will again start animationFadeOut. Pick images from an array and display.
In your Activity.xml layout create a new ImageView, please note I'm not using the attribute android:src="#drawable/...." in this ImageView , like this
<ImageView
android:id="#+id/uno"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
/>
So you will have two imageViews in your Activity.xml finally
1.-Your first image (the original in your code)
<ImageView
android:id="#+id/bsc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="#drawable/your_first_image/>
2.-the new image without android:src attribute
<ImageView
android:id="#+id/uno"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
/>
In your activity class onCreate() define the new image you want to use, of course you need to save this image in your drawable folder, and then set the image with its drawable using setImageResource() method, the code will be something like this;
ImageView nueva = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//....your code...
nueva = (ImageView) findViewById(R.id.uno);
//Here set the new image
nueva.setImageResource(R.drawable.your_new_image);
}
Now just need to add the animations, in onResume() method for example:
#Override
protected void onResume() {
super.onResume();
//the imagen you are using in your code
image.startAnimation(animationFadeOut);
//the new image fadein
nueva.startAnimation(animationFadeIn);
}

An easy way to make GONE animation work

I have a custom search panel, which is a part of main layout. Most of time the panel is hidden. I would like to add appearing/disappearing animation to the panel. Here is the simplified layout excerpt:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/layoutSearch"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" >
<EditText
android:id="#+id/editSearch"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<<Other inner views to be animated>>
</RelativeLayout>
<<Other views, which should not be affected by the animation>>
</LinearLayout>
Try 1: I added animation resources and attach them to the #id/layoutSearch with this line in XML:
android:layoutAnimation="#anim/search_in_layout"
anim/search_in.xml:
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/overshoot_interpolator"
android:fromYDelta="-100%p"
android:toYDelta="0"
android:duration="#android:integer/config_longAnimTime" />
anim/search_in_layout.xml:
<layoutAnimation
xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="#anim/search_in" />
The animation works fine, but only for the panel appearing. The panel disappears in a moment without animation when I hide it with:
mSearchLayout.setVisibility(View.GONE);
Try 2: I guess the above solution does not work as the animation destination parameters match the current panel position. OK, I created two more animation resources: anim/search_out.xml and anim/search_out_layout.xml. The only differences are exchanged "fromYDelta" and "toYDelta" values and updated "android:animation" value. Then I load the resources in the code and set them to the #id/layoutSearch like this:
LayoutAnimationController controller =
AnimationUtils.loadLayoutAnimation(this, R.anim.search_out_layout);
mSearchLayout.setLayoutAnimation(controller);
The "out" animation triggered on calling of setLayoutAnimation(). After the animation the search panel returns to it original position on the screen it had before "out" animation. If I try to call mSearchLayout.setVisibility(View.GONE) just after setLayoutAnimation(), I see no animation, the panel disappears at once.
Try 3: I guess I need to create the animation in the code and then set a listener on it. Then I should call mSearchLayout.setVisibility(View.GONE) in the onAnimationEnd() handler to hide the panel after the animation played. I did not tried this yet. I think it's over complicated.
I guess I missed something important. Is there a way to implement GONE animation a bit easy?
To follow on to the answers above : here is how I solved this problem.
Please note that setting setFillBefore and setFillAfter in your animation will lead to the following bug! Issue 5272: View with visibility View.GONE still generates touch events
http://code.google.com/p/android/issues/detail?id=5272
File : MyWebViewActivity.java
private View mBottomOverlay;
private View mTopOverlay;
private boolean mControlsOverlayVisible;
private Animation mSlideBottomUpAnimation;
private Animation mSlideBottomDownAnimation;
private Animation mSlideTopDownAnimation;
private Animation mSlideTopUpAnimation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reader_layout);
// load the overlay resources
mTopOverlay = findViewById(R.id.reader_overlay_top_toolbar);
mBottomOverlay = findViewById(R.id.reader_overlay_bottom_toolbar);
initAnimations();
}
private void initAnimations() {
final AnimationListener makeTopGone = new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
Log.d(TAG, "onAnimationEnd - makeTopGone");
mTopOverlay.setVisibility(View.GONE);
}
};
final AnimationListener makeBottomGone = new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
Log.d(TAG, "onAnimationEnd - makeBottomGone");
mBottomOverlay.setVisibility(View.GONE);
}
};
final AnimationListener makeTopVisible = new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.d(TAG, "onAnimationStart - makeTopVisible");
mTopOverlay.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {}
};
final AnimationListener makeBottomVisible = new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.d(TAG, "onAnimationStart - makeBottomVisible");
mBottomOverlay.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {}
};
mSlideTopUpAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_top_up);
mSlideBottomDownAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_down);
mSlideTopUpAnimation.setAnimationListener(makeTopGone);
mSlideBottomDownAnimation.setAnimationListener(makeBottomGone);
mSlideTopDownAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_top_down);
mSlideBottomUpAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_up);
mSlideTopDownAnimation.setAnimationListener(makeTopVisible);
mSlideBottomUpAnimation.setAnimationListener(makeBottomVisible);
}
private void hideControlOverlays() {
Log.d(TAG, "hideControlOverlays");
mTopOverlay.startAnimation(mSlideTopUpAnimation);
mBottomOverlay.startAnimation(mSlideBottomDownAnimation);
mControlsOverlayVisible = false;
}
private void showControlOverlays() {
Log.d(TAG, "showControlOverlays");
mTopOverlay.startAnimation(mSlideTopDownAnimation);
mBottomOverlay.startAnimation(mSlideBottomUpAnimation);
mControlsOverlayVisible = true;
}
File : /res/layout/reader_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/reader_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<WebView
android:id="#+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/reader_overlay_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/reader_overlay_top_toolbar"
android:layout_width="fill_parent"
android:layout_height="140dp"
android:background="#80000000" >
<include layout="#layout/toolbar_top" />
</LinearLayout>
<LinearLayout
android:id="#+id/reader_overlay_bottom_toolbar"
android:layout_width="fill_parent"
android:layout_height="140dp"
android:layout_gravity="bottom"
android:background="#80000000"
android:orientation="horizontal" >
<include layout="#layout/toolbar_bottom_left" />
</LinearLayout>
</FrameLayout>
</FrameLayout>
File : /res/anim/slide_bottom_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillEnabled="true"
android:interpolator="#android:anim/accelerate_interpolator" >
<translate
android:duration="#android:integer/config_shortAnimTime"
android:fromYDelta="0"
android:toYDelta="100%" />
</set>
File : /res/anim/slide_bottom_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator" >
<translate
android:duration="#android:integer/config_shortAnimTime"
android:fromYDelta="100%"
android:toYDelta="0" />
</set>
File : /res/anim/slide_top_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator" >
<translate
android:duration="#android:integer/config_shortAnimTime"
android:fromYDelta="-100%"
android:toYDelta="0" />
</set>
File : /res/anim/slide_top_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillEnabled="true"
android:interpolator="#android:anim/accelerate_interpolator" >
<translate
android:duration="#android:integer/config_shortAnimTime"
android:fromYDelta="0"
android:toYDelta="-100%" />
</set>
Try 3: I guess I need to create the animation in the code and then set a listener on it. Then I should call mSearchLayout.setVisibility(View.GONE) in the onAnimationEnd() handler to hide the panel after the animation played. I did not tried this yet. I think it's over complicated.
That's what you should do and actually that's not hard to achieve.
Sample code:
public class YourClass extends Foo implements AnimationListener {
//...
#Override
public void onAnimationEnd(Animation a) {
// Do stuff.
}
#Override
public void onAnimationRepeat(Animation a) {
}
#Override
public void onAnimationStart(Animation a) {
}
}
you need to call setFillAfter() of Animation Class to hold the animation after playing.
RelativeLayout layout = (RelativeLayout) findViewById(R.id.layoutSearch);
Animation a = AnimationUtils.loadAnimation(this, R.anim.push_down);
a=setFillAfter(true);
layout.setLayoutAnimation(new LayoutAnimationController(a));
layout.startLayoutAnimation();
Setting a View to GONE effectively removes it from the layout. Instead you should set it to INVISIBLE, and then GONE after the animation has completed if you need to.

Categories

Resources