Android: How to keep Animation after Animation - android

I'm implementing animation when slide between fragments in ViewPager.
when slide to new fragment I want to scale the view and the make start a set of animation includes alpha and translate animation but when start the set problem is scale animation's result was not keeping (the view return to the original size).
I had tried to with
scaleAnimation.setFillAfter(true);
scaleAnimation.setFillEnabled(true);
But it just work when I do not start set of animation above, When I start the set, the view is return to original size.
Any body can give me a solution?
EDIT:
First thing I want to scale an imageView by animation:
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 1.3f, 1f, 1.3f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 1);
scaleAnimation.setDuration(1000);
scaleAnimation.setFillAfter(true);
scaleAnimation.setFillEnabled(true);
Then I want after scale, ImageView still keep new scale size and start another Animation as:
private void startSetAnimation() {
AnimationSet set = new AnimationSet(true);
set.setDuration(3000);
set.setFillAfter(true);
float alphaS = 1f;
AlphaAnimation alpha = new AlphaAnimation(currentAlpha, alphaS);
alpha.setDuration(3000);
alpha.setFillAfter(true);
float scale = 0.1f;
TranslateAnimation translate = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, currentTrans,
Animation.RELATIVE_TO_SELF, scale,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF , 0f);
translate.setFillAfter(true);
translate.setDuration(3000);
set.addAnimation(translate);
set.addAnimation(alpha);
ivHorizontal.startAnimation(set);
}
So I add below code to scale animation to make it but not success.
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
startSetAnimation();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
ivHorizontal.startAnimation(scaleAnimation);

There is an onAnimationEnd listener you can utilize kick off certain animations when other ones are done. I'll post code when I get to my computer
Edit:
The reason why your imageView doesn't retain its new size after scaling is because Animations aren't permanent, what you need to do is this
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
// change the actual width and height so it doesn't go back to what it was
LayoutParams layoutParams = (LayoutParmas) ivHorizontal.getLayoutParams();
layoutParams.width = ivHorizental.getWidth();
layoutParams.height= ivHorizental.getHeight();
ivHorizontal.setLayoutParams(layoutParams);
ivHorizontal.requestLayout();
startSetAnimation();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
ivHorizontal.startAnimation(scaleAnimation);

Related

Constant velocity in rotate animation

I am using RotateAnimation to spin an ImageView to a certain degree (my ImageView is a circle).
degree_old = degree % 360;
degree = random_sector.nextInt(3600) + 720;
This is the code I use for the first spin:
final RotateAnimation rotate = new RotateAnimation(0, degree, RotateAnimation.RELATIVE_TO_SELF,
0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(5000);
rotate.setFillAfter(true);
rotate.setRepeatCount(0);
rotate.setRepeatMode(0);
rotate.setInterpolator(new DecelerateInterpolator());
And this code to spin to the start position again:
final RotateAnimation rotateBack = new RotateAnimation(degree, (back_degree + degree), RotateAnimation.RELATIVE_TO_SELF,
0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
rotateBack.setDuration(3000);
rotateBack.setFillAfter(true);
rotateBack.setRepeatCount(0);
rotateBack.setRepeatMode(0);
rotateBack.setInterpolator(new LinearInterpolator());
It works.
My problem is that the speed rotation isn't the same every time. Sometimes it spins with a very high velocity and other time with a very low velocity.
My question is: Is there a way to have every time the same velocity? I prefer my animation to spin with a low velocity for 5 seconds.
How can I change the the spinning speed?
Not sure if you are wanting to use only RotateAnimation.
The following code will rotate an Image 360 degrees and back again very smoothly.
Obviously you can adjust this code to include your random generator.
public class MainActivity extends AppCompatActivity {
ImageView my_image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
my_image = findViewById(R.id.my_image);
animate_it();
}
private void animate_it() {
my_image.setRotation(0);
my_image.animate().rotation(360).setDuration(5000).setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
my_image.animate().rotation(0).setDuration(5000);
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
}
}

Android view.setX()/setY() according accelerometer changes, show motion trail animation

I am trying to implement something like:
motion trail animation
motion blur animation
ghost animation
(i do not know correct name of "effect") for repeatedly change view position.
Function, which is called repeatedly according accelerometer changes:
public void setXY(float x, float y) {
if(view != null) {
overloadPoint.setX(pointX);
overloadPoint.setY(pointY);
}
}
My goal:
For change X,Y animation show path (line, curve) between old and new view position.
OR alternative goal:
Between old and new view position, i would like to freeze old position and apply for example alpha effect to view in old position from 1.0f to 0.0f, duration:100ms. So when method is called for example every 50ms, i will see two views. Both views will have fade out effect (alpha 1.0f -> 0.0f), but older will have less alpha.
For: API >= 21
I tried:
public void setXY(float x, float y){
final View view = new View(this);
view.setLayoutParams(new LinearLayout.LayoutParams(
25, //TODO
25)); //TODO
view.setBackgroundResource(R.drawable.background_point);
relativeLayout.addView(view);
view.setX(x);
view.setY(y);
//Variant 1:
view.animate()
.alpha(0f)
.setDuration(750)
.setInterpolator(new DecelerateInterpolator())
.withLayer()
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
relativeLayout.removeView(view);
}
})
.start();
//Variant 2:
/*AlphaAnimation anim1 = new AlphaAnimation(1f, 0f);
anim1.setDuration(750);
//anim1.setFillAfter(true);
anim1.setAnimationListener(new Animation.AnimationListener() {
public void onAnimationStart(Animation anim) {};
public void onAnimationRepeat(Animation anim){};
public void onAnimationEnd(Animation anim) {
relativeLayout.removeView(view);
};
});
view.startAnimation(anim1);*/
//Variant 3:
/*view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.ALPHA, 0f);
// Add a listener that does cleanup
animator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
relativeLayout.removeView(view);
view.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
animator.start();*/
}
But i think, that these are not good solutions.. repeatedly create and remove Views. Better will be effect with one View.
Thank you.

Fade out process of textview animation not working properly

So I have a textview at the top of my screen and eight buttons in the middle. What I would like to happen is for the textview to slide in from the right (animation) and then whenever the user clicks a button it makes the textview fade out, changes the text, and then fade back in with the new text. The fading back in and changing the text works fine, but instead of fading out the textview just disappears. The textview also has a problem with the slide in from the left animation in onCreate so i figured it may be something I am missing to do with the textview. Here is my code, someone please help mehh!!
private void AnimationMethodForButtons(TextView TitleArea, int explanation){
ObjectAnimator fadeOut = ObjectAnimator.ofFloat(TitleArea, "alpha", 1.0f, 0.0f);
fadeOut.setDuration(3000);
fadeOut.start();
ObjectAnimator fadeIn = ObjectAnimator.ofFloat(TitleArea, "alpha", 0.0f, 1.0f);
fadeIn.setDuration(3000);
TitleArea.setText(explanation);
fadeIn.start();
}
The start() call is asynchronous. You should be using an AnimatorListener if you want to do something at the end of an animation.
private void AnimationMethodForButtons(final TextView title, final int explaination){
ObjectAnimator fadeOut = ObjectAnimator.ofFloat(title, "alpha", 1.0f, 0.0f);
fadeOut.setDuration(3000);
final ObjectAnimator fadeIn = ObjectAnimator.ofFloat(title, "alpha", 0.0f, 1.0f);
fadeIn.setDuration(3000);
fadeOut.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
title.setText(explaination);
fadeIn.start();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
fadeOut.start();
}

android translate animation clips the part of view not shown on screen

I have a Relative Layout containing some textviews which floats over a gridview. When I select an item in the grid, the layout moves down to nearly the end of the screen and only about 1/5th of it is visible. This is done using simple Translate Animation. Now when I click another button in the grid, I need to Relative Layout to move back to its original position on top of the gridview. I did this also with Translate Animation and this is happnening, but only the portion of the RelativeLayout which was visible when it was collapsed is translating (moving) and the other portion becomes visible after animation has ended. This looks really ugly.
I know that Android doesnt draw the portion of the view that is not visible on the screen. Is there a way to force draw the full portion ?
My Animation code is given below:
public void smoothExpanderAnimate(final int finalTarget,final RelativeLayout expander,final int animateToY,final boolean setExpanded,final boolean refreshGrid)
{
final RelativeLayout.LayoutParams head_params = (RelativeLayout.LayoutParams)expander.getLayoutParams();
TranslateAnimation anim = new TranslateAnimation(0f, 0f, 0f, animateToY);
anim.setDuration(400);
//timeListHeight = list.getHeight();
//anim.setFillAfter(true);
anim.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
//Should I try something here ?
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
head_params.topMargin = finalTarget;
expander.clearAnimation();
expander.setLayoutParams(head_params);
isExpanded = setExpanded;
isAnimating = false;
if(!setExpanded)
{
setChildHeight(timeListHeight, list);
}
}
});
isAnimating = true;
expander.startAnimation(anim);
}
I found a solution for this.
If you dont need to support lower API levels and are fine with API level 11 onwards, you can use ObjectAnimator for this. ObjectAnimator has a translatey method which works quite well.
If you need to support API 8 onwards, you need to make sure your view comes within the bounds of the screen and then animates. The following code modification did the trick.
I know it seems very weird, do let me know if there is a better way to do this.
public void smoothExpanderAnimate(boolean addSpecialFix,final int finalTarget,final RelativeLayout expander,final int animateToY,final boolean setExpanded,final boolean refreshGrid)
{
final RelativeLayout.LayoutParams head_params = (RelativeLayout.LayoutParams)expander.getLayoutParams();
TranslateAnimation anim = new TranslateAnimation(0f, 0f, 0f, animateToY);
anim.setDuration(400);
expander.setVisibility(View.INVISIBLE); //Make View invisible
if(isExpanded && addSpecialFix){
//THIS IS THE FIX
int old = head_params.topMargin;
head_params.topMargin = finalTarget;
expander.clearAnimation();
expander.setLayoutParams(head_params); //move invisible view to the final position
anim = new TranslateAnimation(0f, 0f, old-closedY, 0);
Log.d("asdasd", old+"");
anim.setDuration(400);
}
//timeListHeight = list.getHeight();
//anim.setFillAfter(true);
anim.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
head_params.topMargin = finalTarget;
expander.clearAnimation();
expander.setLayoutParams(head_params);
isExpanded = setExpanded;
isAnimating = false;
expander.setVisibility(View.VISIBLE);
if(refreshGrid)
{
mCalAdapter.notifyDataSetChanged();
}
if(!setExpanded)
{
setListHeight(timeListHeight, list);
}
}
});
isAnimating = true;
expander.startAnimation(anim);
}

How to animate process of hiding view?

I want to create view that will hide behide other view with nice visual effect. Firstly, I look on Android developer docs and find animatiion framework and write code like this:
Animation animation = new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, -80.0f);
animation.setDuration(200);
animation.setInterpolator(new AccelerateInterpolator());
searchButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
searchContainer.startAnimation(animation);
findViewById(R.id.explore_place_search).setVisibility(View.GONE);
}
});
So I get movement when I click on the button but I want to freeze view on the last position when animation has completed. Better approach move view when user touch this element (MotionEvent.ACTION_DOWN). Can I ask you about how to do that or where I can read about same cases? All help will be appreciated.
Lots of thoughts there... Animations are fairly simple in android, take a look at the api demoes: http://developer.android.com/resources/samples/ApiDemos/index.html
Here is an example of two imageviews fading in and out on top of eachother:
Animation fadeIn = new AlphaAnimation(0.00f, 1.00f);
fadeIn.setDuration(1000);
fadeIn.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {}
public void onAnimationRepeat(Animation animation) {}
public void onAnimationEnd(Animation animation) {}
});
Animation fadeOut = new AlphaAnimation(1.00f, 0.00f);
fadeOut.setDuration(1000);
fadeOut.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {}
public void onAnimationRepeat(Animation animation) {}
public void onAnimationEnd(Animation animation) {
placeholderImageView.setVisibility(View.GONE);
}
});
imageView.setImageBitmap(bitmap);
placeholderImageView.startAnimation(fadeOut);
imageView.startAnimation(fadeIn);
This is done in code but animation can just as well be done with xml.

Categories

Resources