I have this layout for testing some Animations
.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/frame1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#00ff00"
android:orientation="vertical">
<TextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="1"/>
<TextView
android:id="@+id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="2"/>
</LinearLayout>
<LinearLayout
android:id="@+id/frame2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#0000ff">
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/edit_style"/>
</LinearLayout>
</LinearLayout>
What I want to achive is that the ListView list
in the LinearLayout frame2
should grow to the top of the screen, while the LinearLayout frame1
shrinks.
This can be done very easily with the ObjectAnimator
and an AnimatorSet
like this:
ObjectAnimator animframe1 = ObjectAnimator.ofInt(frame1, "bottom", 0);
ObjectAnimator animframe2 = ObjectAnimator.ofInt(frame2, "top", 0);
ObjectAnimator listview = ObjectAnimator.ofInt(list, "bottom", frame2.getBottom());
AnimatorSet set = new AnimatorSet();
set.setDuration(1000L);
set.playTogether(animframe1, animframe2, listview);
set.start();
What I do is manipulating the top
and the bottom
properties of the Views to have the grow/shrink effect.
It works like I want, but with one flaw: While the ListView is growing, the additional items (which are there) aren't visible. The room should be there, but the additional items will only show up if I click the ListView after the animation.
How can I say the ListView that the additional items should be reloaded while the animation runs?
I tried to call list.invalidate()
in an AnimationUpdateListener
but without success. If I call list.requestLayout()
there will be no Animation.
What I have missed is to set the height
of the ListView, after the top
property was modified. Without this the ListView will hold the same old height, which is the reason that no additional items will be shown.
I switched to a ValueAnimator, because there is no need for an additional setter for the height
in a CustomListView class.
Code is like this:
public void animateListHeight() {
PropertyValuesHolder topList = PropertyValuesHolder.ofInt("top", mListView.getTop(), 5);
ValueAnimator animList = ValueAnimator.ofPropertyValuesHolder(topList);
animList.setDuration(300L);
AnimatorUpdateListener listUpdater = new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int top = ((Integer)animation.getAnimatedValue("top")).intValue();
mListView.setTop(top);
ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) mListView.getLayoutParams();
params.height = mListView.getBottom() - top;
mListView.setLayoutParams(params);
}
};
animList.addUpdateListener(listUpdater);
animList.start();
}