I'm doing a small Android app based around a ListView. When the user selects one or more elements in the list and subsequently selects a menu item from the ActionBar I would like to do a small animation on the selected elements in the list, and this is where things go wrong.
Nothing animates - nor does anything fail. The following code piece is a simplified version of what I'm doing:
private void animateListViewItem()
{
TranslateAnimation anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -1.0f,Animation.RELATIVE_TO_SELF, 0.0f);
anim.setDuration(2000);
View v = fragment.getListAdapter().getView(fragment.getListView().getFirstVisiblePosition(), null, null);
v.startAnimation(anim);
}
When I messed around with it, trying to figure out what was wrong, I at one point substituted the item with the entire ListView to rule out the animation as the source of the problem - like this.
private void animateListViewItem()
{
TranslateAnimation anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -1.0f,Animation.RELATIVE_TO_SELF, 0.0f);
anim.setDuration(2000);
fragment.getListView().startAnimation(anim);
}
To my amazement, that worked perfect!
So my question is - why can't I animate the individual elements in a ListView? Or is there something I am doing wrong?
Thanks!
P.S. For the record the ListView is populated with custom views (LinearLayouts), and I have checked that I get the right item before animating.
I found out what the issue was:
View v = fragment.getListAdapter().getView(fragment.getListView().getFirstVisiblePosition(), null, null);
This line was the problem. It returns a new View to display the underlying data at the specified position in the list not the existing View. So the returned View has nothing to do with the list.
Instead doing this:
View v = fragment.getListView().getChildAt(fragment.getListView().getFirstVisiblePosition());
Got me the View that the list was using and the animation worked as expected.
Related
On button click I would like to make an image move either down or right. The issue I am running into is that the movement of the image only occurs once. In onClick() method I am just calling either one of my move methods. Here are the move methods.
private void moveLeftToRight() {
animation = new TranslateAnimation(0.0f, 200.0f, 0.0f, 0.0f);
animation.setDuration(1500); // animation duration
animation.setFillAfter(true);
iv1.startAnimation(animation); // start animation
}
private void moveUpToDown() {
animation = new TranslateAnimation(0.0f, 0.0f, 0.0f, 200.0f);
animation.setDuration(1500); // animation duration
animation.setFillAfter(true);
iv1.startAnimation(animation); // start animation
}
I can call either one of these one time for the first time. Thereafter the animation methods do not work. I am wondering if I need to reset or something. Any ideas? Thanks in advance.
When you pass your coordinates to TranslateAnimation those coordinates are relative to 0,0 and not the views coordinates.
To fix this we will get the views coordinates with view.bottom, view.left etc.
Then add the values you'd like to transform by to those values, pass those to TranslateAnimation, and your translation will work as expected.
I'm looking to implement an animation that will slide open or expand a ListView in android. At the moment, I'm using a scale animation (shown below)
Animation slideDown = new ScaleAnimation(1.0f, 1.0f, 0.0f, 1.0f);
slideDown.setDuration(1000);
but this doesn't work for 2 reasons:
1) I want the first item to fade in, and then the list to drop down. If I do a fade in animation, the entire list shows up and then jumps back up to the top and scales down to full size
2) I'm not really looking to scale, I would like to just reveal the ListView by animating down the bottom (if that makes sense).
Is there a way that I can do a TranslateAnimation on just the bottom margin or something similar? I looked into the drawable Clip resource, but that didn't seem to fit my needs here (I'm not sure how to apply it to a ListView). And I'm using a normal ListView, not an ExpandableListView, because I just have one group of items.
So I started searching for different things and it turns out that animating the height was my solution. Essentially I start with a dummy object in the list (so that it has at least 1 row), then I animate it from the height of that row to the height of the full list. Below is the code for the runnable that I am now calling.
private Runnable slideDownList1 = new Runnable() {
#Override
public void run() {
final ListView detail = (ListView)getView().findViewById(R.id.detail_menu_1);
ValueAnimator va = ValueAnimator.ofInt(detail.getHeight(), detail.getHeight()*mItem.containedObjects.size());
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
detail.getLayoutParams().height = value.intValue();
detail.requestLayout();
}
});
va.setDuration(1000);
va.start();
}
};
The XML is just a basic ListView with the id of detail_menu_1.
The new element Recycler View include animations. You can use it with Support Library
https://developer.android.com/training/material/lists-cards.html
I have searched the forum for this , but found no similar question, okay so I have a customised list view, Each entry in this list is a text view and an image. Suppose the user adds the text in some activity.and presses the save button. When pressing the back button to come back to this list view. The entry just added should swipe in from the right.How can I do that, any example would help.
Here is one working example from bottom to top, I guess you can turn that into right to left ;-)
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//Do the animation once.
if (position > maxposition) {
AnimationSet set = new AnimationSet(true);
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(400);
set.addAnimation(animation);
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 1.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
animation.setDuration(500);
set.addAnimation(animation);
row.startAnimation(set);
maxposition = position;
}
return row;
}
Thank you everyone for your contribution, I did some more digging, and found that interpolators provide animations to views. Referred an example, implemented it and got what I wanted.
I'm using listview animation from API DEMOS, example 2. here's the snippet from OnCreate method:
ListView listview = (ListView) findViewById(android.R.id.list);
AnimationSet set = new AnimationSet(true);
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(50);
set.addAnimation(animation);
animation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
animation.setDuration(200);
set.addAnimation(animation);
LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);
listview.setLayoutAnimation(controller);
At some point in the future, notifyDataSetInvalidated() is called upon list's adapter, and my list is refreshed. but the items are not shown in animation any more.
Please help.
If you want to reanimate your LayoutController after your data set changes, call the method startLayoutAnimation() of the view.
You should check out this thread about difference between notifyDataSetChanged() and notifyDataSetInvalidated() (Link updated to point to Romain Guy's answer!)
In short the difference is:
notifyDataSetChanged: The items in the data set are changed (added / removed / updated / reordered, whatever).
notifyDataSetInvalidated: The data source of the adapter is no longer available.
Here you can find a working sample with notifyDataSetInvalidated function in use. Probably it will do the trick with your animation problem as well.
I have simple ListView that displays data from database. Every after 1 min data are getting refresh automatically. Here is the code snippet I am using to do that :
DataAdapter adp = (DataAdapter) DataList.getAdapter();
adp.UpdateDataList(DataAdapter.DATA_LIST);
adp.notifyDataSetChanged();
DataList.invalidateViews();
DataList.scrollBy(0, 0);
I have created ListView i.e. DataView and dataAdapter that simply extends baseAdapter.
UpdateDataList is simply get data from database and creates an arrayList.
And Adapter notifies view to refresh the Data.
Everything is working perfect.
Now one thing I am trying to do here is when data refresh I need to add some kind of animation so that it becomes eyecaching. And people mark that something happened.
Similar to iPhone application. I do not want to add spinner because data update is synchronize process so data change is quickly without making any new changes in view. Simply numbers got flipped.
Any help will be appreciated....
Here is the code I tried and worked well for me....
/* Setting up Animation */
AnimationSet set = new AnimationSet(true);
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(400);
set.addAnimation(animation);
animation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f
);
animation.setDuration(400);
set.addAnimation(animation);
LayoutAnimationController controller =
new LayoutAnimationController(set, 0.25f);
parent.setLayoutAnimation(controller);
/* Animation code ends */
Maybe you can attach an animation to your ListView, since ListView extends ViewGroup you can do it, read the LayoutAnimationController on android reference: http://developer.android.com/reference/android/view/animation/LayoutAnimationController.html
cheers