I have a recyclerview with a lot of elements (20+) and a lottie animation in each element. The lottie animation doesn't run until the user taps on it but the problem is that when an animation is tapped the animation happens every 5 elements.
For example if you tap on the 1st element, then element 5, 10, 15,20 all animate.
If you tap on the second then 6,11,16,21 all animate.
Here is my View Holder class:
class OutfitViewHolder extends RecyclerView.ViewHolder{
private final LottieAnimationView animationView;
private OutfitViewHolder(View view){
super(view);
animationView = view.findViewById(R.id.wearAgainAnimation);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
wearAgainAnimation();
}
});
}
private void wearAgainAnimation() {
final ValueAnimator animator = ValueAnimator.ofFloat(0f,.5f).setDuration(800);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
animationView.setProgress((Float) animator.getAnimatedValue()) ;
}
});
if (animationView.getProgress() == 0f) {
animator.start();
} else {
animationView.setProgress(0f);
}
}
}
I have checked to make sure that only the position of the tapped element is passed to the adapter so I'm not sure why the other elements are also animating
I ended up changing the cache size of the recyclerview to match my list size. I did this when initializing my recyclerview in my class
recyclerView.setItemViewCacheSize(list.size());
Related
I have a form with a clickeable cardview. Depending on some of the options, I hide the CardView setting its visibility to GONE.
Other form controls below the card come up to occupy the space the cardview was taking. However when clicking in the area the Cardview used to be, the onclick event is fired for the cardview.
I even put a check to verify the visibility before the click action, but the cardview repots VISIBLE (even though its not being shown). I use Butterknife for the onClick event:
#OnClick(R.id.logo_cardview)
public void onLogoClick(){
if (mLogoCardView.getVisibility() == VISIBLE) {
Snackbar.make(this, "Logo clicked", Snackbar.LENGTH_SHORT).show();
showSettingsDialog();
}
}
I hide the Cardview using an animation:
mAlphaAnimation = new AlphaAnimation(1.0f, 0.0f);
mAlphaAnimation.setDuration(200);
mAlphaAnimation.setFillAfter(true);
mHideListener = new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
mMatchInfo.setVisibility(View.GONE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
};
I have a RecylerView which contains a textView as individual item. Based on the requirement, the background image of the textView will be changed on click after checking the present image.
In simple:
onClick textView TV--> check for the background image of the textview TV--> check if the background image of TV is a, then make it b and viceversa
Please find my code below:
viewHolder.addRemove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(viewHolder.clicked==0)
{
viewHolder.addRemove.setBackgroundResource(R.mipmap.added);
viewHolder.clicked=1;
groupSlcArray.add(model.getName().trim());
Log.d("groupArr", Arrays.toString(groupSlcArray.toArray()));
}
else
{
viewHolder.addRemove.setBackgroundResource(R.mipmap.addslcgroup);
viewHolder.clicked=0;
groupSlcArray.remove(model.getName().trim());
Log.d("groupArr", Arrays.toString(groupSlcArray.toArray()));
}
}
});
I am unable to find anyway to get the background resource of the textView for checking.Need your help.This question might seem too simple for some. So please before Outvoting, try to give a solution because I have tried all the possible solutions that I found.Thanks in advance
Try following code :
holder.textview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.textview.getBackground() == getResources().getDrawable(R.drawable.a)){
holder.textview.setBackground(R.drawable.b);
}
else{
holder.textview.setBackground(R.drawable.a);
}
}
});
You have to understand about getView.
Sometimes If you scroll in ListView, This is not an exact Color
So I would like to recommand following ways like this:
1. Add Code on getView
if (groupSlcArray.contain(odel.getName().trim())) {
viewHolder.addRemove.setBackgroundResource(R.mipmap.addslcgroup);
} else {
viewHolder.addRemove.setBackgroundResource(R.mipmap.added);
}
2. Change OnClickListener Event Code
viewHolder.addRemove.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick (View v){
if (groupSlcArray.contain(odel.getName().trim())) {
viewHolder.addRemove.setBackgroundResource(R.mipmap.addslcgroup);
groupSlcArray.remove(model.getName().trim());
Log.d("groupArr", Arrays.toString(groupSlcArray.toArray()));
} else {
viewHolder.addRemove.setBackgroundResource(R.mipmap.added);
groupSlcArray.add(model.getName().trim());
Log.d("groupArr", Arrays.toString(groupSlcArray.toArray()));
}
}
});
Here is a solution that you can use for change background image of each RecyclerView item.
For example, currently, each row of your RecyclerView is a Item, you need to create 1 more field name textViewBackGround for hold the back ground of each row like this
public class Item{
...
public int textViewBackGround = R.drawable.a; // default image a
}
Then in your adapter
public class MyRecyclerViewAdapter extends RecyclerView.Adapter < MyRecyclerViewAdapter.CustomViewHolder > {
private List < Item > itemList;
private Context mContext;
public MyRecyclerViewAdapter(Context context, List < Item > itemList) {
this.itemList = itemList;
this.mContext = context;
}
#Override
public void onBindViewHolder(CustomViewHolder viewHolder, int i) {
Item item = itemList.get(i);
viewHolder.textView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// don't need to get the background of your TextView then change the background, just need to check the datasource. Later on, you absolutely will know that check the datasource for change background of item is a correct way not check the background resource
if (item.textViewBackGround == R.drawable.a) {
viewHolder.textView.setBackgroundResource(R.drawable.b);
item.textViewBackGround = R.drawable.b;
} else {
viewHolder.textView.setBackgroundResource(R.drawable.a);
item.textViewBackGround = R.drawable.a;
}
}
});
viewHolder.textView.setBackgroundResource(item.textViewBackGround); // need to set the background image for `TextView` everytime bind ViewHolder because RecyclerView item will recycle when you scroll (if you don't understand it, you can remove this line, run your app, scroll up/down and you will understand it)
...
}
class CustomViewHolder extends RecyclerView.ViewHolder {
protected TextView textView;
public CustomViewHolder(View view) {
super(view);
...
}
}
}
Currently, by using the default animator android.support.v7.widget.DefaultItemAnimator, here's the outcome I'm having during sorting
DefaultItemAnimator animation video : https://youtu.be/EccI7RUcdbg
public void sortAndNotifyDataSetChanged() {
int i0 = 0;
int i1 = models.size() - 1;
while (i0 < i1) {
DemoModel o0 = models.get(i0);
DemoModel o1 = models.get(i1);
models.set(i0, o1);
models.set(i1, o0);
i0++;
i1--;
//break;
}
// adapter is created via adapter = new RecyclerViewDemoAdapter(models, mRecyclerView, this);
adapter.notifyDataSetChanged();
}
However, instead of the default animation during sorting (notifyDataSetChanged), I prefer to provide custom animation as follow. Old item will slide out via right side, and new item will slide up.
Expected animation video : https://youtu.be/9aQTyM7K4B0
How I achieve such animation without RecylerView
Few years ago, I achieve this effect by using LinearLayout + View, as that time, we don't have RecyclerView yet.
This is how the animation is being setup
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f);
PropertyValuesHolder translationX = PropertyValuesHolder.ofFloat("translationX", 0f, (float) width);
ObjectAnimator animOut = ObjectAnimator.ofPropertyValuesHolder(this, alpha, translationX);
animOut.setDuration(duration);
animOut.setInterpolator(accelerateInterpolator);
animOut.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator anim) {
final View view = (View) ((ObjectAnimator) anim).getTarget();
Message message = (Message)view.getTag(R.id.TAG_MESSAGE_ID);
if (message == null) {
return;
}
view.setAlpha(0f);
view.setTranslationX(0);
NewsListFragment.this.refreshUI(view, message);
final Animation animation = AnimationUtils.loadAnimation(NewsListFragment.this.getActivity(),
R.anim.slide_up);
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
view.setVisibility(View.VISIBLE);
view.setTag(R.id.TAG_MESSAGE_ID, null);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
view.startAnimation(animation);
}
});
layoutTransition.setAnimator(LayoutTransition.DISAPPEARING, animOut);
this.nowLinearLayout.setLayoutTransition(layoutTransition);
and, this is how the animation is being triggered.
// messageView is view being added earlier in nowLinearLayout
for (int i = 0, ei = messageViews.size(); i < ei; i++) {
View messageView = messageViews.get(i);
messageView.setTag(R.id.TAG_MESSAGE_ID, messages.get(i));
messageView.setVisibility(View.INVISIBLE);
}
I was wondering, how I can achieve the same effect in RecylerView?
Here is one more direction you can look at, if you don't want your scroll to reset on each sort (GITHUB demo project):
Use some kind of RecyclerView.ItemAnimator, but instead of rewriting animateAdd() and animateRemove() functions, you can implement animateChange() and animateChangeImpl(). After sort you can call adapter.notifyItemRangeChanged(0, mItems.size()); to triger animation.
So code to trigger animation will look pretty simple:
for (int i = 0, j = mItems.size() - 1; i < j; i++, j--)
Collections.swap(mItems, i, j);
adapter.notifyItemRangeChanged(0, mItems.size());
For animation code you can use android.support.v7.widget.DefaultItemAnimator, but this class has private animateChangeImpl() so you will have to copy-pasted code and changed this method or use reflection. Or you can create your own ItemAnimator class like #Andreas Wenger did in his example of SlidingAnimator. The point here is to implement animateChangeImpl Simmilar to your code there are 2 animations:
1) Slide old view to the right
private void animateChangeImpl(final ChangeInfo changeInfo) {
final RecyclerView.ViewHolder oldHolder = changeInfo.oldHolder;
final View view = oldHolder == null ? null : oldHolder.itemView;
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;
final View newView = newHolder != null ? newHolder.itemView : null;
if (view == null) return;
mChangeAnimations.add(oldHolder);
final ViewPropertyAnimatorCompat animOut = ViewCompat.animate(view)
.setDuration(getChangeDuration())
.setInterpolator(interpolator)
.translationX(view.getRootView().getWidth())
.alpha(0);
animOut.setListener(new VpaListenerAdapter() {
#Override
public void onAnimationStart(View view) {
dispatchChangeStarting(oldHolder, true);
}
#Override
public void onAnimationEnd(View view) {
animOut.setListener(null);
ViewCompat.setAlpha(view, 1);
ViewCompat.setTranslationX(view, 0);
dispatchChangeFinished(oldHolder, true);
mChangeAnimations.remove(oldHolder);
dispatchFinishedWhenDone();
// starting 2-nd (Slide Up) animation
if (newView != null)
animateChangeInImpl(newHolder, newView);
}
}).start();
}
2) Slide up new view
private void animateChangeInImpl(final RecyclerView.ViewHolder newHolder,
final View newView) {
// setting starting pre-animation params for view
ViewCompat.setTranslationY(newView, newView.getHeight());
ViewCompat.setAlpha(newView, 0);
mChangeAnimations.add(newHolder);
final ViewPropertyAnimatorCompat animIn = ViewCompat.animate(newView)
.setDuration(getChangeDuration())
.translationY(0)
.alpha(1);
animIn.setListener(new VpaListenerAdapter() {
#Override
public void onAnimationStart(View view) {
dispatchChangeStarting(newHolder, false);
}
#Override
public void onAnimationEnd(View view) {
animIn.setListener(null);
ViewCompat.setAlpha(newView, 1);
ViewCompat.setTranslationY(newView, 0);
dispatchChangeFinished(newHolder, false);
mChangeAnimations.remove(newHolder);
dispatchFinishedWhenDone();
}
}).start();
}
Here is demo image with working scroll and kinda similar animation
https://i.gyazo.com/04f4b767ea61569c00d3b4a4a86795ce.gif
https://i.gyazo.com/57a52b8477a361c383d44664392db0be.gif
Edit:
To speed up RecyclerView preformance, instead of adapter.notifyItemRangeChanged(0, mItems.size()); you probably would want to use something like:
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
int firstVisible = layoutManager.findFirstVisibleItemPosition();
int lastVisible = layoutManager.findLastVisibleItemPosition();
int itemsChanged = lastVisible - firstVisible + 1;
// + 1 because we start count items from 0
adapter.notifyItemRangeChanged(firstVisible, itemsChanged);
First of all:
This solution assumes that items that are still visible, after the dataset changed, also slide out to the right and later slide in from the bottom again (This is at least what I understood you are asking for)
Because of this requirement I couldn't find an easy and nice solution for this problem (At least during the first iteration). The only way I found was to trick the adapter - and fight the framework to do something that it was not intended for. This is why the first part (How it normally works) describes how to achieve nice animations with the RecyclerView the default way. The second part describes the solution how to enforce the slide out/slide in animation for all items after the dataset changed.
Later on I found a better solution that doesn't require to trick the adapter with random ids (jump to the bottom for the updated version).
How it normally works
To enable animations you need to tell the RecyclerView how the dataset changed (So that it knows what kind of animations should be run). This can be done in two ways:
1) Simple Version:
We need to set adapter.setHasStableIds(true); and providing the ids of your items via public long getItemId(int position) in your Adapter to the RecyclerView. The RecyclerView utilizes these ids to figure out which items were removed/added/moved during the call to adapter.notifyDataSetChanged();
2) Advanced Version: Instead of calling adapter.notifyDataSetChanged(); you can also explicitly state how the dataset changed. The Adapter provides several methods, like adapter.notifyItemChanged(int position),adapter.notifyItemInserted(int position),... to describe the changes in the dataset
The animations that are triggered to reflect the changes in the dataset are managed by the ItemAnimator. The RecyclerView is already equipped with a nice default DefaultItemAnimator. Furthermore it is possible to define custom animation behavior with a custom ItemAnimator.
Strategy to implement the slide out (right), slide in (bottom)
The slide to the right is the animation that should be played if items are removed from the dataset. The slide from bottom animation should be played for items that were added to the dataset. As mentioned at the beginning I assume that it is desired that all elements slide out to the right and slide in from the bottom. Even if they are visible before and after the dataset change. Normally RecyclerView would play to change/move animation for such items that stay visible. However, because we want to utilize the remove/add animation for all items we need to trick the adapter into thinking that there are only new elements after the change and all previously available items were removed. This can be achieved by providing a random id for each item in the adapter:
#Override
public long getItemId(int position) {
return Math.round(Math.random() * Long.MAX_VALUE);
}
Now we need to provide a custom ItemAnimator that manages the animations for the added/removed items. The structure of the presented SlidingAnimator is very similar to theandroid.support.v7.widget.DefaultItemAnimator that is provided with the RecyclerView. Also Notice this is a prove of concept and should be adjusted before used in any app:
public class SlidingAnimator extends SimpleItemAnimator {
List<RecyclerView.ViewHolder> pendingAdditions = new ArrayList<>();
List<RecyclerView.ViewHolder> pendingRemovals = new ArrayList<>();
#Override
public void runPendingAnimations() {
final List<RecyclerView.ViewHolder> additionsTmp = pendingAdditions;
List<RecyclerView.ViewHolder> removalsTmp = pendingRemovals;
pendingAdditions = new ArrayList<>();
pendingRemovals = new ArrayList<>();
for (RecyclerView.ViewHolder removal : removalsTmp) {
// run the pending remove animation
animateRemoveImpl(removal);
}
removalsTmp.clear();
if (!additionsTmp.isEmpty()) {
Runnable adder = new Runnable() {
public void run() {
for (RecyclerView.ViewHolder addition : additionsTmp) {
// run the pending add animation
animateAddImpl(addition);
}
additionsTmp.clear();
}
};
// play the add animation after the remove animation finished
ViewCompat.postOnAnimationDelayed(additionsTmp.get(0).itemView, adder, getRemoveDuration());
}
}
#Override
public boolean animateAdd(RecyclerView.ViewHolder holder) {
pendingAdditions.add(holder);
// translate the new items vertically so that they later slide in from the bottom
holder.itemView.setTranslationY(300);
// also make them invisible
holder.itemView.setAlpha(0);
// this requests the execution of runPendingAnimations()
return true;
}
#Override
public boolean animateRemove(final RecyclerView.ViewHolder holder) {
pendingRemovals.add(holder);
// this requests the execution of runPendingAnimations()
return true;
}
private void animateAddImpl(final RecyclerView.ViewHolder holder) {
View view = holder.itemView;
final ViewPropertyAnimatorCompat anim = ViewCompat.animate(view);
anim
// undo the translation we applied in animateAdd
.translationY(0)
// undo the alpha we applied in animateAdd
.alpha(1)
.setDuration(getAddDuration())
.setInterpolator(new DecelerateInterpolator())
.setListener(new ViewPropertyAnimatorListener() {
#Override
public void onAnimationStart(View view) {
dispatchAddStarting(holder);
}
#Override
public void onAnimationEnd(View view) {
anim.setListener(null);
dispatchAddFinished(holder);
// cleanup
view.setTranslationY(0);
view.setAlpha(1);
}
#Override
public void onAnimationCancel(View view) {
}
}).start();
}
private void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
View view = holder.itemView;
final ViewPropertyAnimatorCompat anim = ViewCompat.animate(view);
anim
// translate horizontally to provide slide out to right
.translationX(view.getWidth())
// fade out
.alpha(0)
.setDuration(getRemoveDuration())
.setInterpolator(new AccelerateInterpolator())
.setListener(new ViewPropertyAnimatorListener() {
#Override
public void onAnimationStart(View view) {
dispatchRemoveStarting(holder);
}
#Override
public void onAnimationEnd(View view) {
anim.setListener(null);
dispatchRemoveFinished(holder);
// cleanup
view.setTranslationX(0);
view.setAlpha(1);
}
#Override
public void onAnimationCancel(View view) {
}
}).start();
}
#Override
public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
// don't handle animateMove because there should only be add/remove animations
dispatchMoveFinished(holder);
return false;
}
#Override
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop) {
// don't handle animateChange because there should only be add/remove animations
if (newHolder != null) {
dispatchChangeFinished(newHolder, false);
}
dispatchChangeFinished(oldHolder, true);
return false;
}
#Override
public void endAnimation(RecyclerView.ViewHolder item) { }
#Override
public void endAnimations() { }
#Override
public boolean isRunning() { return false; }
}
This is the final result:
Update: While Reading the post again I figured out a better solution
This updated solution doesn't require to trick the adapter with random ids into thinking all items were removed and only new items were added. If we apply the 2) Advanced Version - how to notify the adapter about dataset changes, we can just tell the adapter that all previous items were removed and all the new items were added:
int oldSize = oldItems.size();
oldItems.clear();
// Notify the adapter all previous items were removed
notifyItemRangeRemoved(0, oldSize);
oldItems.addAll(items);
// Notify the adapter all the new items were added
notifyItemRangeInserted(0, items.size());
// don't call notifyDataSetChanged
//notifyDataSetChanged();
The previously presented SlidingAnimator is still necessary to animate the changes.
I'm creating an application for Android, and in this moment i want just create a selectable list using a RecyclerView, for this, when a user clicks on an item, I put its id in an array and I change its icon.
The problem is that, when I scroll down and then I scroll up again or when I change fragment, the array still contains all the id of the items, but the icons comes back as before, they don't mantain the new image that I set.
This is the onBindViewHolder metod, this method is the only in the whole project which change the imageview :
List<Integer> selected = new LinkedList<>();
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mBoundString = mValues.get(position);
holder.mTextView.setText(mValues.get(position));
final int pos = position;
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Context context = v.getContext();
Animation to_middle = AnimationUtils.loadAnimation(v.getContext(), R.anim.to_middle);
final Animation from_middle = AnimationUtils.loadAnimation(v.getContext(), R.anim.from_middle);
to_middle.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
holder.mImageView.setImageResource(R.drawable.ic_action_navigation_check);
holder.mImageView.clearAnimation();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
holder.mImageView.setAnimation(to_middle);
holder.mImageView.startAnimation(to_middle);
selected.add(pos);
}
});
if(!selected.contains(position)) {
/* I checked and this method it's not called when
an item is selected, so the following instruction
isn't the cause of my problem, anyway the image
comes back as before */
Glide.with(holder.mImageView.getContext())
.load(R.drawable.ic_default)
.fitCenter()
.into(holder.mImageView);
}
}
I'm sure that R.drawable.ic_default isn't used elsewhere, so which method is changing the image?
Thank you
if(selected.contains(position)) { // Check if already selected
Glide.with(holder.mImageView.getContext())
.load(R.drawable.ic_action_navigation_check) // set selected drawable here.
.fitCenter()
.into(holder.mImageView);
}
You are checking that "if not selected set image to default" but you need to check "if selected set image to selected image".
I have a class where I include another layout on a button click. This included layout has some buttons and a code which executes on clicking these buttons. I have used a counter which indicates the number of times the button is clicked. First time clicking on the button includes the layout and the second time clicking removes the views and so on. Here's the code
public class Home extends Fragment implements OnClickListener {
int c = 0;
Button bmain, bnew, bolder;
RelativeLayout r1;
View rootView;
Animation slidedown, slideup;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.home, container, false);
bmain = (Button) rootView.findViewById(R.id.btn2);
bmain.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View arg0) {
ViewGroup con = null;
LayoutInflater layoutInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
FrameLayout flContainer = (FrameLayout)rootView.findViewById(R.id.flContainer);
//Loading animation
slidedown = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_down);
slideup = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_up);
//The counter indicates the number of clicks.
//Needs to be replaced for a better solution.
//If it's even add view
if(c%2==0)
{
//Adding layout here
flContainer.addView(layoutInflater.inflate(R.layout.test1,con,false ));
//Starting Animation
flContainer.startAnimation(slidedown);
//After adding layout we can find the Id of the included layout and proceed from there
bnew = (Button) rootView.findViewById(R.id.btntest);
bnew.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0) {
Toast.makeText(getActivity(), "You Clicked New", Toast.LENGTH_LONG).show();
}
});
bolder = (Button) rootView.findViewById(R.id.btntest1);
bolder.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0) {
Intent form = new Intent(getActivity(),FeedbackForm.class);
startActivity(form);
}
});
c++;
} //If ends here
//If it's odd remove view
else
{
flContainer.removeAllViews();
flContainer.startAnimation(slideup);
//flContainer.removeView(flContainer);
//flContainer.removeView(layoutInflater.inflate(R.layout.test1, con, false));
c++;
}
}
}
The code at the end
flContainer.removeAllViews();
flContainer.startAnimation(slideup);
removes the view but fails to process the animation. I have tried using removeView but in that case the buttonclicks in the if statement fail to execute the second time. What am I missing here? How can I achieve it?
The answer is pretty simple. You have to remove the view after the animation is finished. This can be achieved pretty simple, first you have to set an animation listener for your animation and in the onAnimationEnd callback - which is called when the animation is finished - you remove the views.
EDIT:
Replace this:
flContainer.removeAllViews();
flContainer.startAnimation(slideup);
With this:
slideup.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
flContainer.removeAllViews();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
flContainer.startAnimation(slideup);
If there are any further problems let me know.