I have a horizontal recyclerView, When I first open the activity I want to make all the items in recyclerview scroll to the bottom (to the right in this case) and back to the top (to the left). Kinda like an animation. Scroll behavior should be visible to the user.
I tried to do it like:
Animation slideRight = AnimationUtils.loadAnimation(this, R.anim.slide_right);
Animation slideLeft = AnimationUtils.loadAnimation(this, R.anim.slide_left);
slideRight.setDuration(1000);
slideLeft.setDuration(1000);
slideRight.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
recyclerView.startAnimation(slideLeft);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
recyclerView.startAnimation(slideRight);
anim slide left:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<translate
android:duration="200"
android:fromXDelta="-100%"
android:fromYDelta="0%"
android:toXDelta="0%"
android:toYDelta="0%" />
</set>
anim slide right:
<translate
android:duration="200"
android:fromXDelta="100%"
android:fromYDelta="0%"
android:toXDelta="0%"
android:toYDelta="0%" />
it works however it just slides the recyclerview as a whole, I just want to scroll(slide) the items. How can I do this?
You can use scrollToPosition()
recyclerView.post(new Runnable() {
#Override
public void run() {
recyclerView.scrollToPosition(adapter.getItemCount() - 1);
// Here adapter.getItemCount()== child count
}
});
or smoothScrollToPosition()
recyclerView.post(new Runnable() {
#Override
public void run() {
recyclerView.smoothScrollToPosition(adapter.getItemCount()- 1);
}
});
To move up again, you need to call the above method with index 0. But first, you need to make sure that the RecyclerView is scrolled to last.
So, put a ScrollListener on RecyclerView to make sure the last item is visible.
Use this..
int top = 0;
recyclerView.smoothScrollToPosition(top); // for top
int bottom = recyclerView.getAdapter().getItemCount()-1;
recyclerView.smoothScrollToPosition(bottom);
if you need scroll item of recyclerview to CENTER of screen when for ex. expand your item - use this way:
in app/build.gradle - insert:
implementation 'com.andkulikov:transitionseverywhere:1.7.4'
when hadle click in onBindViewHolder of adapter - insert:
AutoTransition transitionPort = new AutoTransition();
transitionPort.setDuration(100);
transitionPort.addListener(new Transition.TransitionListener() {
#Override
public void onTransitionStart(#NonNull Transition transition) {
recyclerView.setEnabled(false);
recyclerView.setClickable(false);
}
#Override
public void onTransitionEnd(#NonNull Transition transition) {
recyclerView.post(() -> recyclerView.smoothScrollToPosition(position));
recyclerView.setEnabled(true);
recyclerView.setClickable(true);
}
#Override
public void onTransitionCancel(#NonNull Transition transition) {
recyclerView.setEnabled(true);
recyclerView.setClickable(true);
}
#Override
public void onTransitionPause(#NonNull Transition transition) {
}
#Override
public void onTransitionResume(#NonNull Transition transition) {
}
});
TransitionManager.beginDelayedTransition(recyclerView, transitionPort);
Not working after trying other things?
This excellent piece of code worked for me
private void scrollToBottom(final RecyclerView recyclerView) {
// scroll to last item to get the view of last item
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
final RecyclerView.Adapter adapter = recyclerView.getAdapter();
final int lastItemPosition = adapter.getItemCount() - 1;
layoutManager.scrollToPositionWithOffset(lastItemPosition, 0);
recyclerView.post(new Runnable() {
#Override
public void run() {
// then scroll to specific offset
View target = layoutManager.findViewByPosition(lastItemPosition);
if (target != null) {
int offset = recyclerView.getMeasuredHeight() - target.getMeasuredHeight();
layoutManager.scrollToPositionWithOffset(lastItemPosition, offset);
}
}
});
}
You can modifyline, if you want to jump to some other listitem & not last
final int lastItemPosition = adapter.getItemCount() - 1;
Source
Related
I am making an app that includes recyclerview. The items of recyclerview show up (slide in) with animation from the bottom on activity start. when clicking an item, it navigates to another activity. I want the items to disappear (slide out) with animation before exiting current activity. In my case I want items to drop down (slide out) and then new activity starts. is there any way to sliding out items before exiting activity?
EDIT: something like below:
You need the Slide Animation.
I have used it in one of my Android app. I will explain this with Explode Animation.
Lets say you have 2 activities A(GridList Activity) and B(DetailActivity).
A-->B
You can achieve this in these simple steps
1. Enable Content Transition
Add this code in your style.xml
<item name="android:windowContentTransitions">true</item>
2. Set Default enter and exit Animation
Write this method in Activity A which will handle animation for you.
public void setAnimation()
{
if(Build.VERSION.SDK_INT>20) {
Explode explode = new Explode();
explode.setDuration(1000);
explode.setInterpolator(new DecelerateInterpolator());
getWindow().setExitTransition(explode);
getWindow().setEnterTransition(explode);
}
}
3. Start Activity with Intent
Add this in your Activity A for starting Activity B. Note that the animation works only above SDK>20. So if your min sdk is lower then you will have to a check for SDK as well. Just use this code snippet and you will be good to go.
public void startActivity(){
Intent i = new Intent(BlankActivity.this, AllImageActivity.class);
i.putStringArrayListExtra(MOVIE_LIST, movie.getImages());
if(Build.VERSION.SDK_INT>20)
{
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(BlankActivity.this);
startActivity(i,options.toBundle());
}
else {
startActivity(i);
}
}
Very Important
You should place the setAnimation() before setContentView(R.layout.yourLayout) else the animation will not work. So the Activity A should look like this
Activity A extends .... {
#Override
protected void onCreate(Bundle savedInstaceState)
{
super.onCreate(savedInstaceState);
setAnimation();
setContentView(R.layout.image_landing_layout);
startActivity(); // Use as you wish
.......
}
public void setAnimation(){
..........
}
I am not writing this on any IDE so don't mind any syntax errors. But this will push you in the right track.
You may checkout my Repository . But you may have hard time finding it there. Hope this helps.
LayoutAnimationController:
Using the build in LayoutAnimationController you can achieve the slide out effect using a custom animation slide from top to bottom with animation order to be the LayoutAnimationController.ORDER_REVERSE to start the animation from the bottom right child item view.
1.)Declare in your res/anim/slide_from_top_to_bottom.xml the slide out animation:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="250">
<translate
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:fromYDelta="0"
android:toYDelta="100%p"/>
<alpha
android:fromAlpha="1"
android:toAlpha="0"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"/>
</set>
2.)Use the below helper to start the above animation by setting the LayoutAnimationController into the RecyclerView using the setLayoutAnimation() method:
private void slideOutRecyclerViewLayoutAnimation(final RecyclerView recyclerView)
{
Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_from_top_to_bottom);
animation.setFillAfter(true); //true if the animation should apply its transformation after it ends
LayoutAnimationController lac = new LayoutAnimationController(animation);
lac.setOrder(LayoutAnimationController.ORDER_REVERSE);
lac.setDelay(0.15f);
recyclerView.setLayoutAnimation(lac);
recyclerView.getAdapter().notifyDataSetChanged();
recyclerView.scheduleLayoutAnimation();
//go to the next Activity after 1sec
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//go to the next Activity
}
}, 1000);
}
Custom ItemAnimator:
In case you want to have more customisation in the animation delay of each child with a different slide out order something like in your gif you can use a custom SimpleItemAnimator and use the public boolean animateRemove(RecyclerView.ViewHolder holder) which is called when an item in the RecyclerView has been removed. It called when you remove only one item like notifyItemRemoved() or when you remove a range of items like notifyItemRangeRemoved().
1.)Create the CustomAnimator like the below sample:
public class CustomAnimator extends SimpleItemAnimator {
private final int columns;
private final int rows;
public CustomAnimator(int columns, int itemsCount){
this.columns = columns;
this.rows = (int) Math.ceil((double) itemsCount / (double)columns);
}
#Override
public boolean animateRemove(RecyclerView.ViewHolder holder) {
//to get the item view position set in RecyclerView.Adapter#onBindViewHolder the position to the item view like: itemView.setTag(position);
int position = (int)holder.itemView.getTag();
int x = position % columns;
int y = position / columns;
int yDiff = rows - y;
long delay = 0;
switch (x)
{
//column 0
case 0:
delay = yDiff * 60L;
break;
//column 1
case 1:
delay = yDiff * 50L;
break;
//column 2
case 2:
delay = yDiff * 40L;
break;
//column 3
case 3:
delay = yDiff * 30L;
break;
}
int height = holder.itemView.getContext().getResources().getDisplayMetrics().heightPixels;
holder.itemView.setTranslationY(0);
holder.itemView.setAlpha(1);
holder.itemView.animate()
.translationY(height)
.alpha(0)
.setInterpolator(new LinearInterpolator())
.setDuration(500)
.setStartDelay(delay)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
dispatchRemoveFinished(holder);
}
})
.start();
return false;
}
#Override
public boolean animateAdd(RecyclerView.ViewHolder holder) {
return false;
}
#Override
public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
return false;
}
#Override
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop) {
return false;
}
#Override
public void runPendingAnimations() {
}
#Override
public void endAnimation(#NonNull RecyclerView.ViewHolder item) {
}
#Override
public void endAnimations() {
}
#Override
public boolean isRunning() {
return false;
}
}
2.)In your RecyclerView.Adapter in onBindViewHolder set the position of each item into the tag to be retrieved later from the CustomAnimator like below:
itemView.setTag(position);
3.)During the RecyclerView initialisation set the ItemAnimator like below:
//set GridLayoutManager with 4 columns
recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
//prepare some dummy items
List<Item> itemsList = new ArrayList<>();
for(int i =0; i<26; i++) {
itemsList.add(new Item());
}
//initialize Adapter
itemsAdapter = new MyAdapter(itemsList);
//set recyclerView Adapter
recyclerView.setAdapter(itemsAdapter);
//set recyclerView CustomAnimator
recyclerView.setItemAnimator(new CustomAnimator(4, itemsAdapter.getItems().size()));
4.)Finally when you click on an item call the below helper to start the animation:
private void removeAllItems(){
int itemsCount = itemsAdapter.getItems().size();
itemsAdapter.getItems().clear();
recyclerView.getAdapter().notifyItemRangeRemoved(0, itemsCount);
//go to the next Activity after 1sec
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//go to the next Activity after 1sec
}
}, 1000);
}
Result:
I have a listview. I want to add one animation that is if I select one list item then it will be removed and rest of the items below that item will be shifted up with slide up animation. I have done this with linear layout by getting its child position but I am not able to understand how to slide up rest elements of listview. Please help
Below is my code for animation in dynamically created linear layout
plus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Animation animation1 = AnimationUtils.loadAnimation(getActivity(), R.anim.move);
final Animation animation2 = AnimationUtils.loadAnimation(getActivity(), R.anim.moveup);
this is animation of that item on which we click
lay1.startAnimation(animation1);
this is code for animation rest child to slide up
final int i = lay1.getId() + 1;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 100ms
try {
LinearLayout l = (LinearLayout) layoutall.getChildAt(i);
l.startAnimation(animation2);
layoutall.removeView(lay1);
} catch (Exception e) {
//connectToDatabase();
}
}
}, 600);
Updated Code
Thanks a lot. I was able to implement this functionality but problem is that I have used two animation in one listview but not able to implement first animation.
My code for list item to whom I want to swipe left while on click
viewHolder.accept.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
removeListItem(viewHolder.order_card_layout, position);
}
});
And code for animation is
protected void removeListItem(final View rowView, final int positon) {
// TODO Auto-generated method stub
final Animation animation = AnimationUtils.loadAnimation(rowView.getContext(), R.anim.move);
rowView.startAnimation(animation);
Animation.AnimationListener al = new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation arg0) {
ViewHolder vh = (ViewHolder) rowView.getTag();
//vh.needInflate = true;
}
#Override public void onAnimationRepeat(Animation animation) {}
#Override public void onAnimationStart(Animation animation) {}
};
collapse(rowView, al);
}
but problem is that My first animation is not working that is slide right
final Animation animation = AnimationUtils.loadAnimation(rowView.getContext(), R.anim.move);
rowView.startAnimation(animation);
New Updated Code
I was able to implement this functionality but problem is that I have used two animations and want to do first animation on that item whom I click and another animation on all the list items below that clicked item.But my problem is that the item on which I clicked slide right and also it re appears and slide up with whole list but I want that the item on which i click will be slide right and rest will be slide up.
My code for list item to whom I want to swipe left while on click
viewHolder.accept.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
removeListItem(viewHolder.order_card_layout, position);
}
});
And code for animation is
protected void removeListItem(final View rowView, final int positon) {
// TODO Auto-generated method stub
final Animation animation = AnimationUtils.loadAnimation(rowView.getContext(), R.anim.move);
rowView.startAnimation(animation);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 100ms
try {
Animation.AnimationListener al = new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation arg0) {
ViewHolder vh = (ViewHolder) rowView.getTag();
//vh.needInflate = true;
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
};
collapse(rowView, al);
} catch (Exception e) {
//connectToDatabase();
}
}
}, 600);
}
private void collapse(final View v, Animation.AnimationListener al) {
final int initialHeight = v.getMeasuredHeight();
Animation anim = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1) {
v.setVisibility(View.GONE);
}
else {
v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
v.requestLayout();
}
}
#Override
public boolean willChangeBounds() {
return true;
}
};
if (al!=null) {
anim.setAnimationListener(al);
}
anim.setDuration(600);
v.startAnimation(anim);
}
Here is code related to your requirement , Try this
https://github.com/paraches/ListViewCellDeleteAnimation
Download code and run it.
if you want to see demo than see this video,
http://www.youtube.com/watch?v=bOl5MIti7n0
Here is Code, where i am implementing both animation.
1) Slide from right while click on List-view Item-click.
2) while clicking on Delete Button, slide-up animation for remaining rows in list-view (which is already done in link i have given).
Copy below files to your anim folder.
1) fade_out.xml :
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<alpha
android:duration="700"
android:fromAlpha="1"
android:toAlpha="0" />
</set>
2) fade_in.xml :
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<alpha
android:duration="700"
android:fromAlpha="0"
android:toAlpha="1" />
</set>
3) slide_in_right.xml :
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:duration="700"
android:fromXDelta="100%"
android:toXDelta="0%" />
</set>
4) slide_out_right.xml :
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:duration="700"
android:fromXDelta="0%"
android:toXDelta="100%" />
</set>
Now add below methods and class to your activity,
//Animation
private void fadeOutView(View view) {
Animation fadeOut = AnimationUtils.loadAnimation(view.getContext(), R.anim.fade_out);
if (fadeOut != null) {
fadeOut.setAnimationListener(new ViewAnimationListener(view) {
#Override
protected void onAnimationStart(View view, Animation animation) {
}
#Override
protected void onAnimationEnd(View view, Animation animation) {
view.setVisibility(View.GONE);
}
});
view.startAnimation(fadeOut);
}
}
private void fadeInView(View view) {
Animation fadeIn = AnimationUtils.loadAnimation(view.getContext(), R.anim.fade_in);
if (fadeIn != null) {
fadeIn.setAnimationListener(new ViewAnimationListener(view) {
#Override
protected void onAnimationStart(View view, Animation animation) {
view.setVisibility(View.VISIBLE);
}
#Override
protected void onAnimationEnd(View view, Animation animation) {
}
});
view.startAnimation(fadeIn);
}
}
private void slideInView(View view) {
Animation slideIn = AnimationUtils.loadAnimation(view.getContext(), R.anim.slide_in_right);
if (slideIn != null) {
slideIn.setAnimationListener(new ViewAnimationListener(view) {
#Override
protected void onAnimationStart(View view, Animation animation) {
view.setVisibility(View.VISIBLE);
}
#Override
protected void onAnimationEnd(View view, Animation animation) {
}
});
view.startAnimation(slideIn);
}
}
private void slideOutView(View view) {
Animation slideOut = AnimationUtils.loadAnimation(view.getContext(), R.anim.slide_out_right);
if (slideOut != null) {
slideOut.setAnimationListener(new ViewAnimationListener(view) {
#Override
protected void onAnimationStart(View view, Animation animation) {
}
#Override
protected void onAnimationEnd(View view, Animation animation) {
view.setVisibility(View.GONE);
}
});
view.startAnimation(slideOut);
}
}
private abstract class ViewAnimationListener implements Animation.AnimationListener {
private final View view;
protected ViewAnimationListener(View view) {
this.view = view;
}
#Override
public void onAnimationStart(Animation animation) {
onAnimationStart(this.view, animation);
}
#Override
public void onAnimationEnd(Animation animation) {
onAnimationEnd(this.view, animation);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
protected abstract void onAnimationStart(View view, Animation animation);
protected abstract void onAnimationEnd(View view, Animation animation);
}
Now, if you want to display animation on List Item Click then, give animation in Adapter class in which you have inflate raw_layout for listView.
5) raw_layout.xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/linLayout">
<ImageButton
android:id="#+id/cell_trash_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="#drawable/trash_can"
android:scaleType="fitXY" />
<TextView
android:id="#+id/cell_name_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:layout_marginLeft="16dp"
android:layout_weight="1"
android:text="cell name" />
</LinearLayout>
6) finally Apply animation to your Parent Layout of raw_layout in getView() method of adapter onClick of Parent Layout.Here My parent layout for raw_layout is LinearLayout which have id named linLayout.
vh.linLayout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (vh.linLayout.getVisibility() == View.VISIBLE) {
fadeOutView(vh.linLayout);
slideInView(vh.linLayout);
} else {
fadeInView(vh.linLayout);
slideOutView(vh.linLayout);
}
}
});
i have tried this and its working. So try this once!!
The animation starts when I clicked the ball.
It just moves down then to top then to the middle again.
However, the second onClick in the ball only works if I click in the middle, meaning the ball physically moves but the function's still in the middle.
How do I set its position according to the animation?
(The second click will cancel the animation)
onClick :
public void ballChange(View v)
{
isClicked = false;
if (ballstarted == false)
{
L1_animation = AnimationUtils.loadAnimation(this, R.anim.mercury_anim);
L1_Ball2.startAnimation(L1_animation);
ct = new CountDownTimer(4000, 1000)
{
#Override
public void onTick(long millisUntilFinished)
{
}
#Override
public void onFinish()
{
if (isClicked == false)
{
lifeline-=1;
if (lifeline == 0)
{
Toast.makeText(getApplicationContext(), "Gameover dude",
Toast.LENGTH_LONG).show();
heart.setText(""+lifeline);
GameOverDialog wp = new GameOverDialog(getApplicationContext());
wp.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
wp.show();
wp.setCancelable(false);
Mercury_L1.L1_Ball.clearAnimation();
Mercury_L1.L1_countDownTimer.cancel();
Mercury_L1.timerHasStarted = false;
Mercury_L1.isCancelled = true;
}
else
{
Toast.makeText(getApplicationContext(), String.valueOf(lifeline), Toast.LENGTH_SHORT).show();
heart.setText(""+lifeline);
minuslife.setVisibility(View.VISIBLE);
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
minuslife.setVisibility(View.GONE);
}
}, 500);
Mercury_L1.this.v.vibrate(500);
}
}
}
}.start();
ballstarted = true;
Toast.makeText(getApplicationContext(), String.valueOf(ballstarted), Toast.LENGTH_SHORT).show();
}
else
{
L1_Ball2.clearAnimation();
ballstarted = false;
}
}
You are doing a view animation which only updates the place the ball is drawn and not its actual location. You should use a property animation like objectanimator. Below is some sample code for how to do that with XML.
public void doObjectAnimatorXML(){
AnimatorSet object = (AnimatorSet) AnimatorInflater.loadAnimator(getActivity(),R.animator.property_animator);
object.addListener(new AnimatorListenerAdapter(){
#Override
public void onAnimationEnd(Animator animation) {
simpleLock= false;
}
});
object.setInterpolator(new LinearInterpolator());
object.setTarget(mLittleChef); //mLittleChef is the view
object.start();
}
And the XML
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially" >
<objectAnimator
android:propertyName="x"
android:duration="1000"
android:valueTo="138"
android:valueType="floatType"/>
<objectAnimator
android:propertyName="x"
android:duration="1000"
android:valueTo="276"
android:valueType="floatType"/>
</set>
I'm trying to create an animation buttons. I have 3 buttons. I created an animation as I need to. and applied it to the buttons. but it is performed on all buttons simultaneously. I want her to be followed sequentially. first there is the first button, then the second, then a third.
my animation:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<alpha
android:duration="1000"
android:fromAlpha="0.0"
android:startOffset="0"
android:toAlpha="1.0" >
</alpha>
<translate
android:fromXDelta="-100%"
android:duration="1000"
android:toXDelta="0" />
</set>
in my class onCreateView:
Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.falling);
Button kitchenBtn = (Button) v.findViewById(R.id.buttonKitchen);
Button hotelBtn = (Button) v.findViewById(R.id.buttonHotel);
Button engenerBtn = (Button) v.findViewById(R.id.buttonEngener);
kitchenBtn.setAnimation(animation);
hotelBtn.setAnimation(animation);
engenerBtn.setAnimation(animation);
buttons go from the left edge. I want to start with the first left, then the second and third behind her. Now they do it at the same time.
FULL CODE:
public class PurchaseMenu extends Fragment implements View.OnClickListener {
private int mAnimationsFinished = 0;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.purchase_menu, null);
final Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.falling);
final Button kitchenBtn = (Button) v.findViewById(R.id.buttonKitchen);
final Button hotelBtn = (Button) v.findViewById(R.id.buttonHotel);
final Button engenerBtn = (Button) v.findViewById(R.id.buttonEngener);
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.d("mylognah","start"+" "+mAnimationsFinished);
}
#Override
public void onAnimationEnd(Animation animation) {
if (mAnimationsFinished == 0) { //kitchenBtn animation ended
hotelBtn.setAnimation(animation);
} else if (mAnimationsFinished == 1) { //hotelBtn animation ended
engenerBtn.setAnimation(animation);
}
mAnimationsFinished++; //This would be a member variable
Log.d("mylognah","finish"+" "+mAnimationsFinished);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
kitchenBtn.setAnimation(animation);
kitchenBtn.setOnClickListener(this);
hotelBtn.setOnClickListener(this);
engenerBtn.setOnClickListener(this);
return v;
}
You have to set an AnimationListener on the Animation and keep track of the number of times it finished and start the appropriate next Animation like so:
final Animation fallingAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.falling);
final Button kitchenBtn = (Button) v.findViewById(R.id.buttonKitchen);
final Button hotelBtn = (Button) v.findViewById(R.id.buttonHotel);
final Button engenerBtn = (Button) v.findViewById(R.id.buttonEngener);
fallingAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
if (mAnimationsFinished == 0) { //Kitchen animation ended
kitchenBtn.setAnimation(null); //Set the animation on the other button to null
engenerBtn.setAnimation(null); //Otherwise they animate too
hotelBtn.setVisibility(View.VISIBLE); //Make the view visible
hotelBtn.setAnimation(fallingAnimation);
fallingAnimation.start(); //Restart animation. DO NOT FORGET THIS ONE
} else if (mAnimationsFinished == 2) { //Hotel animation ended. I couldn't figure out why, but this won't work when you try == 1.
kitchenBtn.setAnimation(null); //Set the animation on the other button to null
hotelBtn.setAnimation(null); //Otherwise they animate too
engenerBtn.setVisibility(View.VISIBLE); //Make the view visible
engenerBtn.setAnimation(fallingAnimation);
fallingAnimation.start(); //Restart animation. DO NOT FORGET THIS ONE
}
mAnimationsFinished++;
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
kitchenBtn.setAnimation(fallingAnimation);
hotelBtn.setVisibility(View.INVISIBLE); //Make view invisible. Otherwise they're visible before animated
engenerBtn.setVisibility(View.INVISIBLE); //Make view invisible. Otherwise they're visible before animated
This way, the kitchedBtn will be animated first and when the Animation ended, the onAnimationEnd method will be called, starting the next Animation.
using startOffSet you can avoid the issue. like this:
Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.falling);
Button kitchenBtn = (Button) v.findViewById(R.id.buttonKitchen);
Button hotelBtn = (Button) v.findViewById(R.id.buttonHotel);
Button engenerBtn = (Button) v.findViewById(R.id.buttonEngener);
kitchenBtn.setAnimation(animation);
animation.setStartOffset(animation.getDuration());
hotelBtn.setAnimation(animation);
animation.setStartOffset(animation.getDuration()*2);
engenerBtn.setAnimation(animation);
Lets say you have a LinearLayout(or any viewgroup) that you want to add these buttons dynamically. You can do like this:
for (int i = 0; i < buttons.size(); i++) {
Button button = new Button(context);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
linearLayout.addView(button);
animateButton(button);
}
}, BUTTON_DELAY_DURATION * i);
}
and dont forget to call handler.removeCallBacks() to remove runnable instance in onPause();
I want to make a layout animated through translation animation from screen's particular X Y position. and this is happening very correcty. now the problem starts when animations completes the layout again go to screen's top rihgt corner. i want the layout stay at the same position on which the animation ends.
AnimationListener animationListener = new AnimationListener() {
#Override
public void onAnimationEnd(Animation arg0) {
drawer_layout.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation animation) {
drawer_layout.setVisibility(View.VISIBLE);
}
};
final Animation animTranslate = AnimationUtils.loadAnimation(this,
R.anim.top_to_bottom_in);
animTranslate.setAnimationListener(animationListener);
drawer_layout = (LinearLayout) findViewById(R.id.drawer_layout);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// bitmapBackground = CaptureBackground();
faded_layout.setBackgroundColor(Color.parseColor("#50ffffff"));
// HandleDropAnimation(drawer_layout);
drawer_layout.startAnimation(animTranslate);
}
});
and this is my xml.
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromYDelta="25%p"
android:toYDelta="50%p" />
Call
animTranslate.setFillAfter(true);
before you start the animation. According to java docs:
If fillAfter is true, the transformation that this animation performed will persist when it is finished.
use before animation starts
animTranslate.setFillAfter(true);