I'm trying to use the new property animations to play layout animations when I'm toggling between two components in one container.
I simply call this code:
public void onClick(View v) {
if (componentOneVisible) {
componentOne.setVisibility(View.GONE);
componentTwo.setVisibility(View.VISIBLE);
} else {
componentTwo.setVisibility(View.GONE);
componentOne.setVisibility(View.VISIBLE);
}
componentOneVisible = !componentOneVisible;
}
My animations are set as following:
final ObjectAnimator testIn = ObjectAnimator.ofPropertyValuesHolder(
componentContainer,
PropertyValuesHolder.ofFloat("scaleX", 0, 1f),
PropertyValuesHolder.ofFloat("scaleY", 0, 1f),
PropertyValuesHolder.ofFloat("alpha", 0f, 1f));
testIn.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator anim) {
View view = (View) ((ObjectAnimator) anim).getTarget();
view.setScaleX(1f);
view.setScaleY(1f);
view.setAlpha(1f);
}
});
testIn.setDuration(3000);
final ObjectAnimator testOut = ObjectAnimator.ofPropertyValuesHolder(
componentContainer,
PropertyValuesHolder.ofFloat("scaleX", 1f, 0),
PropertyValuesHolder.ofFloat("scaleY", 1f, 0),
PropertyValuesHolder.ofFloat("alpha", 1, 0f));
testOut.setDuration(3000);
testOut.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator anim) {
View view = (View) ((ObjectAnimator) anim).getTarget();
view.setScaleX(0f);
view.setScaleY(0f);
view.setAlpha(0f);
}
});
mTransitioner.setAnimator(LayoutTransition.APPEARING, testIn);
mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, testOut);
mTransitioner.setDuration(5000);
mTransitioner.setDuration(LayoutTransition.APPEARING, 3000);
mTransitioner.setDuration(LayoutTransition.DISAPPEARING, 3000);
For some reason only the appearing animation is played when the components are switched. What I'm hoping to see is to first see disappearing animation and then appearing animation.
I also call this code to set the transitioner
mTransitioner = new LayoutTransition();
componentContainer.setLayoutTransition(mTransitioner);
Any ideas?
Related
There is a common recyclerview animation I see in some apps. When recyclerview is populated for the first time , its items slide in from bottom while also fading in at the same time. How to achieve this ?
setItemAnimator() is used for item changes/ new insertion/ deletion. It will not work at first time, if you are using setAdapter() with items.
Try this inside the Recycler view adapter:
int lastPosition = -1;
#Override
public void onViewAttachedToWindow(final ViewHolder holder) {
super.onViewAttachedToWindow(holder);
final long delayTime = 200;
holder.card.setVisibility(View.INVISIBLE);
if (holder.getPosition() > lastPosition) {
holder.card.getHandler().postDelayed(new Runnable() {
#Override
public void run() {
holder.card.setVisibility(View.VISIBLE);
ObjectAnimator alpha = ObjectAnimator.ofFloat(holder.card, "alpha", 0f, 1f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(holder.card, "scaleY", 0f, 1f);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(holder.card, "scaleX", 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(alpha).with(scaleY).with(scaleX);
animSet.setInterpolator(new OvershootInterpolator());
animSet.setDuration(400);
animSet.start();
}
}, delayTime);
lastPosition = holder.getPosition();
} else {
holder.card.setVisibility(View.VISIBLE);
}
}
You can change the AnimatorSet and Interpolator as your need.
Like:
PropertyValuesHolder translateX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, 0, 0);
PropertyValuesHolder translateY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 100, 0);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(holder.itemView, translateX, translateY);
AnimatorSet animSet = new AnimatorSet();
animSet.play(animator);
animSet.setInterpolator(new AccelerateDecelerateInterpolator());
animSet.setDuration(400);
animSet.start();
Try this way to animate recycerview
RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator();
itemAnimator.setAddDuration(1000);
itemAnimator.setRemoveDuration(1000);
recyclerView.setItemAnimator(itemAnimator);
https://www.sitepoint.com/mastering-complex-lists-with-the-android-recyclerview/
http://www.birbit.com/recyclerview-animations-part-1-how-animations-work/
https://www.studytutorial.in/android-recyclerview-with-animation-tutorial
https://github.com/gabrielemariotti/RecyclerViewItemAnimators
https://github.com/couchbaselabs/mini-hacks/tree/master/android-recycler-view-animations
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.
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);
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();
}
i'm using a floating button on my application but i want to do the conversion to toolbar like show on the video, somebody have a sample for that?, if don't have don't worry i'm start to develop but i want a guide, thanks
i have this option:
ViewCompat.animate(view).setDuration(1000).scaleYBy(1).scaleXBy(1).start();
or this option:
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, transitionView, EXTRA_IMAGE);
sample video
i founded the solution, i don't have the same result, but works for me, i post my code:
private void animateBottomToolbar() {
AnimatorSet set = new AnimatorSet().setDuration(500L);
if(bottomToolbarShowing) {
//hide toolbar
set.playTogether(
ObjectAnimator.ofFloat(toolbarBottom, "scaleY", 1.0f, 0.0f),
ObjectAnimator.ofFloat(addButton, "scaleY", 0.0f, 1.0f)
);
set.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationStart(animation);
addButton.setVisibility(View.VISIBLE);
toolbarBottom.setVisibility(View.GONE);
animation.removeAllListeners();
}
});
set.setInterpolator(new OvershootInterpolator());
set.start();
bottomToolbarShowing = false;
} else {
//show toolbar
if (floatMenuOpen) animateFloatingMenu();
set.playTogether(
ObjectAnimator.ofFloat(toolbarBottom, "scaleY", 0.0f, 1.0f),
ObjectAnimator.ofFloat(addButton, "scaleY", 1.0f, 0.0f)
);
set.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
addButton.setVisibility(View.GONE);
toolbarBottom.setVisibility(View.VISIBLE);
animation.removeAllListeners();
inflateMenuOnBottomToolbar();
}
});
set.setInterpolator(new OvershootInterpolator());
set.start();
bottomToolbarShowing = true;
}
}