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
Related
I'm trying to fade out items when it's removed then collapse recycleview. But it doesn't work.
Please help me
for(Object appData : mInvisibleEntries){
mVisibleEntries.remove(appData);
}
for(View view:viewHoldersList){
Animation a = new AlphaAnimation(1.00f, 0.00f);
a.setDuration(2000);
view.startAnimation(a);
}
notifyItemRangeRemoved(MAX_VISIBLE_APPS_COUNT + 1, mInvisibleEntries.size());
collapseRv();
private void collapseRv(){
final int initialHeight = mRecyclerView.getMeasuredHeight();
ValueAnimator valueAnimator = ValueAnimator.ofInt(initialHeight,HEIGHT_VIEW_APPDATA*3+HEIGHT_SECTION_FOOTER);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
mRecyclerView.getLayoutParams().height = (int) animation.getAnimatedValue();
mRecyclerView.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(2000);
valueAnimator.start();
}
To make it simlpe, You can use library like https://github.com/wasabeef/recyclerview-animators
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);
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;
}
}
In my application I have made chathead
I can change position of this chathead using
windowManager.updateViewLayout(chatHead, params);
But it does not change position with animation.
How can I get animation on move
I have tried following but it does not work.
TranslateAnimation anim = new TranslateAnimation( 0, params.x, 0, params.y);
anim.setDuration(1000);
chatHead.startAnimation(anim);
Have you checked the params.x and params.y value is correct or not?
TranslateAnimation anim = new new TranslateAnimation( 0, params.x, 0, params.y);
anim.setDuration(1000);
anim.setAnimationListener(new TranslateAnimation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) { }
#Override
public void onAnimationRepeat(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation)
{
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)chatHead.getLayoutParams();
**//set margin according to your calculation**
params.topMargin = mTopMargin;
params.leftMargin = 0;
chatHead.setLayoutParams(params);
});
chatHead.startAnimation(anim);
}
or
use anim.setFillAfter(true);
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?