I am animating a Relativelayout in my application that has a spinner in it.The layout animates just fine but the problem is I cannot select the Spinner after the animation.I am new to animation.Please Help me!!Below is the code:
MainActivity.java:
Animation slideup=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.slide_up);
relativeLayout1.startAnimation(slideup);
slideup.setFillAfter(true);
slide_up(anim):
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0%p"
android:toYDelta="-20%p"
android:duration="2000"/>
</set>
This is because Animations affects only the drawing of widget. However, The real Location is not affected -It is still in the previous one-.
To overcome this problem, you need to update the layout parameters of the Spinner manually by installing an animation listener as follows:
Animation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation arg0) {
}
public void onAnimationRepeat(Animation arg0) {
//TODO Auto-generated method stub
}
public void onAnimationEnd(Animation arg0) {
android.widget.LinearLayout.LayoutParams params = new LayoutParams(
android.widget.LinearLayout.LayoutParams.FILL_PARENT,
android.widget.LinearLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = addLocationButton.getTop()-100;
Spinner.setLayoutParams(params);
}
});
for more detail visit here : TranslateAnimated ImageView not clickable after animation [Android]
Related
I know that exist a topic similar with this Question but I cant figure how to make this work with my code.
I have one popupwindow, (I dont even know if this is the best way to do what I want but Im new on Android), but I have done a popupWindow appear on click of a image with a animation that I found here, after I read a Question about how to animate the popupwindow and that I have todo the animation of the Enter and the Exit, I figure how to do that, but now my Question:
I dont know how to do the popupwindow dismiss after the Enter Animatio ends.
popupWindow code:
LayoutInflater inflater = (LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View viewAnimationResourceEarned = inflater.inflate(R.layout.layout_animation_resources_earned, null);
animationResourceEarned = new PopupWindow(viewAnimationResourceEarned, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
animationResourceEarned.setAnimationStyle(R.style.styleAnimationResourceEarned);
animationResourceEarned.showAtLocation(viewAnimationResourceEarned, Gravity.CENTER, 0, 0);
Enter Animation code:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:toXScale="1.0"
android:fromXScale="0.0"
android:toYScale="1.0"
android:fromYScale="0.0"
android:pivotX="0%"
android:pivotY="50%"
android:startOffset="100"
android:duration="300" />
<translate
android:fromYDelta="0"
android:toYDelta="-50"
android:duration="2500"/>
</set>
I want to dismiss the popup window after the Enter Animation end, My objective is the popupappear, move to the top a litle and diseppear
You can use the animation listener.
You have to define the animation in an animation variable like this
Animation animation = AnimationUtils.loadAnimation(this, R.style.styleAnimationResourceEarned);
And then,
animation.setAnimationListener(new Animation.AnimationListener() {
#Override public void onAnimationStart(Animation animation) {
}
#Override public void onAnimationEnd(Animation animation) {
//Dismiss it
}
#Override public void onAnimationRepeat(Animation animation) {
} });
Bruno,
Faced the same issue. Unfortunately there is currently no way to get a callback to animation used in popupwindow. I did a small workaround using countdowntimer.
Not perfect - but works well. Hope it helps.
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
#Override
public void onDismiss() {
new CountDownTimer(animationDuration, 10) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
toggle();
}
}.start();
}
});
Additionally to get the animation duration from resource file use following code
int[] attrs = {android.R.attr.windowExitAnimation};
TypedArray ta = context.obtainStyledAttributes(R.style.PopUpMenuAnimation, attrs);
int resID = ta.getResourceId(0,0);
Animation anim = AnimationUtils.loadAnimation(context, resID);
final long animationDuration = anim.getDuration();
I have Linear Layouts that i want to replace each other on click.
At start: Linear Layout A is visible, Linear Layout B is gone
I want when A is clicked to be gone and B to be visible and vice versa.
without the animation it all worked just fine, but when i set animation after clicking B B is gone, but A is not visible although if i click in its place the Log gives me that it's visible
here's the code, any help would be appreciated
private void switchRowItems(final LinearLayout toBeHiddenRow,final LinearLayout toBeShownRow){
toBeHiddenRow.animate()
.rotation(toBeHiddenRow.getHeight()/2)
.alpha(0.0f)
.setDuration(300)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
toBeHiddenRow.clearAnimation();
toBeHiddenRow.setVisibility(View.GONE);
toBeShownRow.clearAnimation();
toBeShownRow.setVisibility(View.VISIBLE);
}
});
//toBeShownRow.clearAnimation();
// toBeShownRow.setVisibility(View.VISIBLE);
}
and the on click checker is as simple as:
if (llRowTwoItemOne.getVisibility() == View.VISIBLE) {
Log.d("llRowTwoItemOne","visible");
} else {
Log.d("llRowTwoItemOne","not visible");
}
I do it in this way:
Create xml file in res/anim resource directory. Let's call it myanimation.xml and write there:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:duration="300">
</rotate>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="200">
</alpha>
</set>
You can see that it is a set of animations you need: rotation and alpha.
Then I write in the switchRowItem function this:
private void switchRowItems(final LinearLayout toBeHiddenRow, final LinearLayout toBeShownRow){
Animation anim = AnimationUtils.loadAnimation(this, R.anim.myanimation);
anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
toBeHiddenRow.setVisibility(View.GONE);
toBeShownRow.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
toBeHiddenRow.startAnimation(anim);
}
That's all. It works pretty well. Hope this is what you asked for.
Ok.. I got this animation set up for a small imageview for translating from "0%" to "50%" in XML...
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<translate
android:duration="400"
android:fromXDelta="0%"
android:toXDelta="+50%" />
</set>
After this, I need to add another sequential animation which would change the Y co-ordinate from "0%" to "50%".. I tried adding another <set> but it did not work... What should I do to get sequential animation?
You can use android:startOffset to delay animations. Delay in milliseconds before the animation runs, once start time is reached. Must be an integer value, such as "100". -- "developer.android.com"
Another way is you can use AnimationListener to "listen" animations and do whatever you want.
This link is useful for you: How to run several translate animations sequentially?
I'm not completly sure what you really want to do, but if you want to "translate" both the "x" and "y" at the same time simply add android:fromYDelta="0%" and android:toYDelta="+50%" to your existing <translate>.
If you want to "translate" the Y values after the X ones, you will need a new XML file, which you will need to call when the X ones finish.
A quick, untested example:
mAnimatedView = findViewById(R.id.viewToAnimate);
mAnimX = (TranslateAnimation) AnimationUtils.loadAnimation(mContext, R.anim.aX);
mAnimY = (TranslateAnimation) AnimationUtils.loadAnimation(mContext, R.anim.aY);
mAnimX.setAnimationListener(new AnimationListener(){
#Override
public void onAnimationEnd(Animation animation) {
if (mAnimatedView) {
mAnimatedView.startAnimation(mAnimY);
}
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
});
mAnimY.setAnimationListener(new AnimationListener(){
#Override
public void onAnimationEnd(Animation animation) {
if (mAnimatedView) {
mAnimatedView.startAnimation(mAnimX);
}
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
});
mAnimatedView.startAnimation(mAnimX);
Hope that helps and is clear enough.
I'm trying to set up 2 layouts - I want one layout to slide up, and when it's finished another layout should fade in.
I've managed to get it working, but at the end of the two animation and first layout blinks once.
How can I solve it?
Here's the code(first layout is named titleLay and the second one is called registerLayout)-
final TranslateAnimation slide = new TranslateAnimation(0, 0, 0,-100 );
slide.setDuration(500);
slide.setFillAfter(true);
slide.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
RelativeLayout registerLayout = (RelativeLayout) findViewById(R.id.registerLay);
Animation fadeInAnimation = AnimationUtils.loadAnimation(con, R.anim.fade_in_anim);
registerLayout.startAnimation(fadeInAnimation);
registerLayout.setVisibility(View.VISIBLE);
}
});
titleLay.startAnimation(slide);
And that's the XML code of the R.anim.fade_in_anim-
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="500"/>
</set>
Edit: If I use other types of animations(fade out, slide etc...) it works fine, without flicking.
Thanks!
If you are using animateLayoutChanges in your layout file in combination with the animation onAnimationEnd toggling the View visibility it will result in two animations running and the view flashing or blinking. Setting view visibility causes the layouts animateLayoutChanges to run and to fade the view in once and then the animation you created causes a second animation to run as well.
Instead of setting the view's visibility, try to use the setAlpha function.
registerLayout.setAlpha(0f); //invisible
registerLayout.setAlpha(1f); //visible
Remove the declerations and initilizations from your onAnimationEnd, the initilization may take a long time since the XML needs to be parsed from resources,
put thouse two lines in your onCreate:
RelativeLayout registerLayout = (RelativeLayout) findViewById(R.id.registerLay);
Animation fadeInAnimation = AnimationUtils.loadAnimation(con, R.anim.fade_in_anim);
and set visibility to slide:
final TranslateAnimation slide = new TranslateAnimation(0, 0, 0,-100 );
slide.setDuration(500);
slide.setFillAfter(true);
slide.setAnimationListener(new
AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
registerLayout.startAnimation(fadeInAnimation);
registerLayout.setVisibility(View.VISIBLE);
}
});
titleLay.startAnimation(slide);
titleLay.setVisibilty(View.VISIBLE);
I'm having some troubles with a slideshow I'm building.
I've created 2 animations in xml for fade in and fade out:
fadein.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="2000"/>
</set>
fadeout.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="2000"/>
</set>
What Im'trying to do, is to change images from an ImageView using the fade effect, so the currently displayed image will fade out, and another one will fade in.
Considering that I have an image already set, I can fadeout this Image without problem, with this:
Animation fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.your_fade_in_anim);
imageView.startAnimation(fadeoutAnim);
But then, I set the next image to be displayed:
imageView.setImageBitmap(secondImage);
It just shows up in the imageView, and when i set the animation it hides the image, the fade it in... Is there any way to fix that, I mean, when I do imageView.setImageBitmap(secondImage); command, the image do not shows up immediately, and only when the fade in animation is executed?
I wanted to achieve the same goal as you, so I wrote the following method which does exactly that if you pass it an ImageView and a list of references to image drawables.
ImageView demoImage = (ImageView) findViewById(R.id.DemoImage);
int imagesToShow[] = { R.drawable.image1, R.drawable.image2,R.drawable.image3 };
animate(demoImage, imagesToShow, 0,false);
private void animate(final ImageView imageView, final int images[], final int imageIndex, final boolean forever) {
//imageView <-- The View which displays the images
//images[] <-- Holds R references to the images to display
//imageIndex <-- index of the first image to show in images[]
//forever <-- If equals true then after the last image it starts all over again with the first image resulting in an infinite loop. You have been warned.
int fadeInDuration = 500; // Configure time values here
int timeBetween = 3000;
int fadeOutDuration = 1000;
imageView.setVisibility(View.INVISIBLE); //Visible or invisible by default - this will apply when the animation ends
imageView.setImageResource(images[imageIndex]);
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator()); // add this
fadeIn.setDuration(fadeInDuration);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator()); // and this
fadeOut.setStartOffset(fadeInDuration + timeBetween);
fadeOut.setDuration(fadeOutDuration);
AnimationSet animation = new AnimationSet(false); // change to false
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
animation.setRepeatCount(1);
imageView.setAnimation(animation);
animation.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
if (images.length - 1 > imageIndex) {
animate(imageView, images, imageIndex + 1,forever); //Calls itself until it gets to the end of the array
}
else {
if (forever){
animate(imageView, images, 0,forever); //Calls itself to start the animation all over again in a loop if forever = true
}
}
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
}
To implement this the way you have started, you'll need to add an AnimationListener so that you can detect the beginning and ending of an animation. When onAnimationEnd() for the fade out is called, you can set the visibility of your ImageView object to View.INVISIBLE, switch the images and start your fade in animation - you'll need another AnimationListener here too. When you receive onAnimationEnd() for your fade in animation, set the ImageView to be View.VISIBLE and that should give you the effect you're looking for.
I've implemented a similar effect before, but I used a ViewSwitcher with 2 ImageViews rather than a single ImageView. You can set the "in" and "out" animations for the ViewSwitcher with your fade in and fade out so it can manage the AnimationListener implementation. Then all you need to do is alternate between the 2 ImageViews.
Edit:
To be a bit more useful, here is a quick example of how to use the ViewSwitcher. I have included the full source at https://github.com/aldryd/imageswitcher.
activity_main.xml
<ViewSwitcher
android:id="#+id/switcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:inAnimation="#anim/fade_in"
android:outAnimation="#anim/fade_out" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="#drawable/sunset" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="#drawable/clouds" />
</ViewSwitcher>
MainActivity.java
// Let the ViewSwitcher do the animation listening for you
((ViewSwitcher) findViewById(R.id.switcher)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewSwitcher switcher = (ViewSwitcher) v;
if (switcher.getDisplayedChild() == 0) {
switcher.showNext();
} else {
switcher.showPrevious();
}
}
});
Have you thought of using TransitionDrawable instead of custom animations?
https://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html
One way to achieve what you are looking for is:
// create the transition layers
Drawable[] layers = new Drawable[2];
layers[0] = new BitmapDrawable(getResources(), firstBitmap);
layers[1] = new BitmapDrawable(getResources(), secondBitmap);
TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
imageView.setImageDrawable(transitionDrawable);
transitionDrawable.startTransition(FADE_DURATION);
I used used fadeIn animation to replace new image for old one
ObjectAnimator.ofFloat(imageView, View.ALPHA, 0.2f, 1.0f).setDuration(1000).start();
you can do it by two simple point and change in your code
1.In your xml in anim folder of your project, Set the fade in and fade out duration time not equal
2.In you java class before the start of fade out animation, set second imageView visibility Gone then after fade out animation started set second imageView visibility which you want to fade in visible
fadeout.xml
<alpha
android:duration="4000"
android:fromAlpha="1.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:toAlpha="0.0" />
fadein.xml
<alpha
android:duration="6000"
android:fromAlpha="0.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:toAlpha="1.0" />
In you java class
Animation animFadeOut = AnimationUtils.loadAnimation(this, R.anim.fade_out);
ImageView iv = (ImageView) findViewById(R.id.imageView1);
ImageView iv2 = (ImageView) findViewById(R.id.imageView2);
iv.setVisibility(View.VISIBLE);
iv2.setVisibility(View.GONE);
animFadeOut.reset();
iv.clearAnimation();
iv.startAnimation(animFadeOut);
Animation animFadeIn = AnimationUtils.loadAnimation(this, R.anim.fade_in);
iv2.setVisibility(View.VISIBLE);
animFadeIn.reset();
iv2.clearAnimation();
iv2.startAnimation(animFadeIn);
For infinite Fade In and Out
AlphaAnimation fadeIn=new AlphaAnimation(0,1);
AlphaAnimation fadeOut=new AlphaAnimation(1,0);
final AnimationSet set = new AnimationSet(false);
set.addAnimation(fadeIn);
set.addAnimation(fadeOut);
fadeOut.setStartOffset(2000);
set.setDuration(2000);
imageView.startAnimation(set);
set.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) { }
#Override
public void onAnimationRepeat(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation) {
imageView.startAnimation(set);
}
});
I'm using this kind of routine for programmatically chaining animations.
final Animation anim_out = AnimationUtils.loadAnimation(context, android.R.anim.fade_out);
final Animation anim_in = AnimationUtils.loadAnimation(context, android.R.anim.fade_in);
anim_out.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation)
{
////////////////////////////////////////
// HERE YOU CHANGE YOUR IMAGE CONTENT //
////////////////////////////////////////
//ui_image.setImage...
anim_in.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {}
});
ui_image.startAnimation(anim_in);
}
});
ui_image.startAnimation(anim_out);
The best and the easiest way, for me was this..
->Simply create a thread with Handler containing sleep().
private ImageView myImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shape_count); myImageView= (ImageView)findViewById(R.id.shape1);
Animation myFadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fadein);
myImageView.startAnimation(myFadeInAnimation);
new Thread(new Runnable() {
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
Log.w("hendler", "recived");
Animation myFadeOutAnimation = AnimationUtils.loadAnimation(getBaseContext(), R.anim.fadeout);
myImageView.startAnimation(myFadeOutAnimation);
myImageView.setVisibility(View.INVISIBLE);
}
};
#Override
public void run() {
try{
Thread.sleep(2000); // your fadein duration
}catch (Exception e){
}
handler.sendEmptyMessage(1);
}
}).start();
}
This is probably the best solution you'll get. Simple and Easy. I learned it on udemy.
Suppose you have two images having image id's id1 and id2 respectively and currently the image view is set as id1 and you want to change it to the other image everytime someone clicks in. So this is the basic code in MainActivity.java File
int clickNum=0;
public void click(View view){
clickNum++;
ImageView a=(ImageView)findViewById(R.id.id1);
ImageView b=(ImageView)findViewById(R.id.id2);
if(clickNum%2==1){
a.animate().alpha(0f).setDuration(2000); //alpha controls the transpiracy
}
else if(clickNum%2==0){
b.animate().alpha(0f).setDuration(2000); //alpha controls the transpiracy
}
}
I hope this will surely help