Preventing overlapping layout animations on a ListView - android

I have a listView that has a layout animation that fades in each item one at a time.
lac = new LayoutAnimationController(AnimationUtils.loadAnimation(this, R.anim.listview_2), 0.25f);
listOptions.setLayoutAnimation(lac);
listOptions.setLayoutAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
When the user selects an item, the listView displays a new set of items - each fading in one at a time. However, if the fade in animation of the items has not completed when the user selects an item and causes a new set to fade in, then these animations overlap causing and the previous items can be seen while the new ones are fading in. It looks like a blinking glitch on the ListView.
onItemClick(), even if I call listView.getLayoutAnimation.getAnimation().cancel(); I still get the same blinking problem.
I have also tried listView.clearAnimation();, still didn't work.
I have also tried: listView.setLayoutAnimation(null); and resetting. Still didn't work.
It appears I am unable to stop or cancel the animation!
All I want to do is, onItemclick() in my listView, to stop the animation or empty / clear the listView then reload the new items into the listView and fade them in using the animation, with no overlap - and therefore - no blinking glitch.
I do not want to disable the listView until the animation completes, then re-enable, because it can create awkwardly long wait times.

Animation in ListViews are challenging which is one of the reasons Google released RecyclerView. However, this video may have some clues for how to make this work for you: https://www.youtube.com/watch?v=8MIfSxgsHIs

Related

Adding Custom Animation when Removing Item RecyclerView

I would like to show a custom animation to match the other animations that I have in my RecyclerView. I can’t find a straight forward way of adding custom animations for removal. I know that when RecyclerView replaced ListView one of the talking points was the ability to know when items are added or removed rather than simply saying the dataset has changed and updating everything, so I figured there would be an easy way to add an animation to a View when it is removed that I am missing.
When I add an animation to a view that is removed the animation will not play. This is likely because the View is removed and the animation stops. Is there an easy way to add an animation to a View that doesn’t get cut off? I'm assuming that I could use a second thread, but I want to know if I am missing something.
//code for removal
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//animation to be added here on view
list.remove(holder.getAdapterPosition());
notifyItemRemoved(position);
notifyItemRangeChanged(position,list.size()-position);
}
});
All add/change/delete/move animations in recyclerView are made by ItemAnimator (by default animator is DefaultItemAnimator). So if you need custom delete animation you should provide custom ItemAnimator via recyclerView.setItemAnimator(animator) method.
I suggest to extend from SimpleItemAnimator and override animateRemove method.

Update View positions after TransitionManager.go(Scene,Transition)

I was creating animation between 2 Scenes using TransitionManager.go(Scene,Transition) and everything worked just fine but after the animation finished I was no longer capable of clicking on the button which was moved from the center of the screen to the left side.
Looking around the Internet I found that this animation actually doesn't even move the Views, just animates them so I have to update their positions to new ones.
Isn't there any better way to do this than manually .setLayoutParams for all the Views in the Scene?
I realized that my Views actually were in the right positions after the animation but I had to reset my OnClickListeners every time Scenes changed
Transition.TransitionListener listener = new Transition.TransitionListener() {
#Override
public void onTransitionEnd(Transition transition) {
//get view references from the new Scene and
//reassign on click listeners to them
}
}
I just assigned this listener to my Transition and everything worked fine.
Here is the post that helped me see my mistake.

Make SwipeRefreshLayout animation invisible

If its possible make Swipe refresh layout animation fully invisible? I want to make whole animation (including loading and cricle with arrow when pulling down gesture) dissapear but I want to be able to use the onRefresh function. Maybe you know any alternatives that I can use in my listview (OnScroll change listener and OverScroll doesnt work for me accroding to trigger the bottom overscoll in my listview and I don wont to trigger my function when the list is swipe up and relase to scroll itself up - the Swipe refresh layout handle it very well for me)
protected void onCreate(Bundle savedInstanceState) {
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(NewActivity.this);
swipeRefreshLayout.setEnabled(false);
swipeRefreshLayout.setRefreshing(false);
}
#Override
public void onRefresh() {
Log.i(TAG, "refresh");
}
Update: According to yours hints I tried to implemented in several ways ( using only setEnabled(false) or setRefreshing(false) or both but in that case the onRefresh function didnt trigger at all.
Use ..
Edited
From the documentation:
If an activity wishes to show just the progress animation, it should call setRefreshing(true). To disable the gesture and progress animation, call setEnabled(false) on the view.
So to show the animation:
swiprefreshLayout.setEnabled( true );
swiperefreshLayout.setRefreshing( true );
And to hide the animation:
swiperefreshLayout.setRefreshing( false );
swiprefreshLayout.setEnabled( false );

How to programmatically initiate a swipe to dismiss with RecyclerView

When I delete an item from a RecyclerView I want to show a "swipe" animation, that is that the item is moved sideways off the screen. I believe there is support for "swipe to dismiss" using ItemTouchHelper, but this is touch-initiated whereas I want to be able to initiate the swipe programmatically.
I have also tried setting the RecyclerView item animator by extending DefaultItemAnimator. Using this method I can get items to swipe left and right but unfortunately the gap in the list closes quickly such that the swipe does not finish before the list item gap has closed.
Anyone know how to do this?
You can use ItemAnimators offered by this library. More specifically, your would use their SlideInLeftAnimator or SlideInRightAnimator.
Although it's already answered with external library; probably someone wants to do it with raw java.. I have done it with the solution in here
The idea is that, you take off the list item view of the RecyclerView to be deleted and animate it; and normally remove it from the adapter
private void removeListItem(View rowView, final int position) {
Animation anim = AnimationUtils.loadAnimation(this,
android.R.anim.slide_out_right);
anim.setDuration(500);
rowView.startAnimation(anim);
new Handler().postDelayed(new Runnable() {
public void run() {
values.remove(position); //Remove the current content from the array
adapter.notifyDataSetChanged(); //Refresh list
}
}, anim.getDuration());
}

Android: Setting ListView fast scroll based on visible positions

I am trying to set the fast scroll enabled and visible if there are more items in the list than are currently visible. After setting the adapter, the ListView's count is properly increased but the last visible position is not. As a result I am currently posting a Runnable to wait until the ListView has figured out what items are / aren't visible. The code is as follows:
listView.post(new Runnable(){
#Override
public void run() {
if(listView.getLastVisiblePosition() < (listView.getCount() - 1)){
listView.setFastScrollAlwaysVisible(true);
listView.setFastScrollEnabled(true);
}
}
});
This solution works fine, but feels a bit hackish. Is there a way to know when the last visible position is updated without posting the runnable? Thanks in advance!

Categories

Resources